__kernel void ps2mesh(
    __global float* in_mesh_face_barycenters,
    //__global float* in_mesh_normals,
    //__global unsigned int* in_mesh_indices,
    __global float* in_ps_points,
    //__global float* in_ps_normals,
    unsigned int num_faces,
    unsigned int num_points,
    __global unsigned int* out_closest_indices
    )
{
    size_t tid = get_global_id(0);
    
    if (tid >= num_points)
        return;

    float3 p,vtx;
    float d,dist = FLT_MAX;
    unsigned int closest_idx, i;

    p = (float3)(in_ps_points[tid*3+0], in_ps_points[tid*3+1], in_ps_points[tid*3+2]);

    for (i=0; i < num_faces; ++i)
    {
        vtx = (float3)(in_mesh_face_barycenters[i*3+0], in_mesh_face_barycenters[i*3+1], in_mesh_face_barycenters[i*3+2]);
        d = distance(vtx, p);

        if (d < dist)
        {
            dist = d;
            closest_idx = i;
        }
    }

    out_closest_indices[tid] = closest_idx;
}


//__kernel void ps2mesh(
//    __global float* in_mesh_vertices,
//    //__global float* in_mesh_normals,
//    //__global unsigned int* in_mesh_indices,
//    __global float* in_ps_points,
//    //__global float* in_ps_normals,
//    unsigned int num_vertices,
//    unsigned int num_points,
//    __global unsigned int* out_closest_indices
//    )
//{
//    size_t tid = get_global_id(0);
//
//    if (tid >= num_points)
//        return;
//
//    float3 p,vtx;
//    float d,dist = FLT_MAX;
//    unsigned int closest_idx, i;
//
//    p = (float3)(in_ps_points[tid*3+0], in_ps_points[tid*3+1], in_ps_points[tid*3+2]);
//
//    for (i=0; i < num_vertices; ++i)
//    {
//        vtx = (float3)(in_mesh_vertices[i*3+0], in_mesh_vertices[i*3+1], in_mesh_vertices[i*3+2]);
//        d = distance(vtx, p);
//
//        if (d < dist)
//        {
//            dist = d;
//            closest_idx = i;
//        }
//    }
//
//    out_closest_indices[tid] = closest_idx;
//}

__kernel void mesh2ps(
    __global float* in_mesh_vertices,
    //__global float* in_mesh_normals,
    //__global unsigned int* in_mesh_indices,
    __global float* in_ps_points,
    //__global float* in_ps_normals,
    unsigned int num_vertices,
    unsigned int num_points,
    __global unsigned int* out_closest_indices,
    __global unsigned int* out_closest_distance
    )
{
    size_t tid = get_global_id(0);

    if (tid >= num_vertices)
        return;

    float3 p,vtx;
    float d,dist = FLT_MAX;
    unsigned int closest_idx, i;

    //p = (float3)(in_ps_points[tid*3+0], in_ps_points[tid*3+1], in_ps_points[tid*3+2]);
    p = (float3)(in_mesh_vertices[tid*3+0], in_mesh_vertices[tid*3+1], in_mesh_vertices[tid*3+2]);

    for (i=0; i < num_points; ++i)
    {
        vtx = (float3)(in_ps_points[i*3+0], in_ps_points[i*3+1], in_ps_points[i*3+2]);
        d = distance(vtx, p);

        if (d < dist)
        {
            dist = d;
            closest_idx = i;
        }
    }

    out_closest_indices[tid]  = closest_idx;
    out_closest_distance[tid] = dist;
}


__kernel void ps2ps(
    __global float* src_points,
    __global float* tar_points,
    unsigned int num_src_points,
    unsigned int num_tar_points,
    __global unsigned int* out_closest_indices
    )
{
    size_t tid = get_global_id(0);

    if (tid >= num_src_points)
        return;

    float3 p_src,p_tar;
    float d,dist = FLT_MAX;
    unsigned int closest_idx, i;

    p_src = (float3)(src_points[tid*3+0], src_points[tid*3+1], src_points[tid*3+2]);

    for (i=0; i < num_tar_points; ++i)
    {
        p_tar = (float3)(tar_points[i*3+0], tar_points[i*3+1], tar_points[i*3+2]);
        d = distance(p_tar, p_src);

        if (d < dist)
        {
            dist = d;
            closest_idx = i;
        }
    }

    out_closest_indices[tid] = closest_idx;
}
