Skip to content

conatsera/k4a_cuda

Folders and files

NameName
Last commit message
Last commit date

Latest commit

0ba351b · Aug 2, 2019

History

16 Commits
Jul 14, 2019
Aug 2, 2019
Aug 2, 2019
Jul 24, 2019
Jul 14, 2019
Aug 2, 2019
Aug 1, 2019
Aug 2, 2019

Repository files navigation

k4a_cuda

A K4A library that wraps functionality from the K4A and K4ABT C SDKs for use in Unity C# scripts. This library performs the point cloud calculation in CUDA as described in the SDK examples.

Script example

using System;
using System.Runtime.InteropServices;
using UnityEngine;

unsafe public class GenerateCloud : MonoBehaviour
{
    ParticleSystem ps;

    [StructLayout(LayoutKind.Sequential)]
    public struct float4
    {
        public float x;
        public float y;
        public float z;
        public float w;
    }

    [DllImport("k4a_cuda_win.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    static extern void init_cpc(bool color, bool body_tracking);

    [DllImport("k4a_cuda_win.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    static extern void get_capture();

    [DllImport("k4a_cuda_win.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    static extern void setup_point_cloud(ref float4[] point_positions, ref uint[] point_colors);

    [DllImport("k4a_cuda_win.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    static extern void get_point_cloud();

    [DllImport("k4a_cuda_win.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    static extern uint get_point_count();

    [DllImport("k4a_cuda_win.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    static extern int get_max_point_count();

    float4[] point_positions;
    uint[] point_colors;

    void Start()
    {
        ps = GetComponent<ParticleSystem>();

        init_cpc(true, false);

        int max_points = get_max_point_count();

        point_positions = new float4[max_points];
        point_colors = new uint[max_points];

        GC.KeepAlive(point_positions);
        GC.KeepAlive(point_colors);

        setup_point_cloud(ref point_positions, ref point_colors);
    }

    void Update()
    {
        get_capture();
        get_point_cloud();
        uint point_count = get_point_count();

        for (int i = 0; i < point_count; i++)
        {
            byte[] color_bits = BitConverter.GetBytes(point_colors[i]);
            ParticleSystem.EmitParams ep = new ParticleSystem.EmitParams
            {
                position = new Vector3(point_positions[i].x, point_positions[i].y, point_positions[i].z),
                startColor = new Color32(color_bits[2], color_bits[1], color_bits[0], 0xFF)
            };

            ps.Emit(ep, 1);
        }
    }
}

Notes

  • This project has been build and tested using CUDA 10.1 and Visual Studio 16 2019
  • dnn_model.onnx is not path-searched and is required with your application (in "<output>/<Name>_Data/" for Unity)
  • Calculating and displaying approximately 6M points per second, running a DNN model, and running a game engine does require a fairly powerful system. I've had success (albeit with a 1/4 to 1/2 second delay) on a GTX 960M and with minimal delay on GTX 1080
  • Set your CUDA version with -DCMAKE_CUDA_COMPILER="<path-to-cuda/bin>/nvcc.exe""

Further work

  • As with the last point above, there are several place I could optimize my code to improve the overall performance. This is my first C++ project on a system with more than 1MB of RAM, so any suggestions/pull requests are welcome.
  • Use a remote system for processing the point cloud and body tracking

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published