在统一中,您如何在给定的世界空间位置找到体素信息?

In unity, how do you find voxel information at a given worldspace position?

我正在尝试制作一款游戏object,如果其中有另一个 object,它会统一对声音做出反应。我希望游戏 object 使用输入 object 的位置来查看最接近的体素,然后根据体素 intensity/colour 播放音频。有人有什么想法吗?我正在使用 512x256x512 体素的数据集。如果 object 也被调整大小,我希望它能工作。非常感谢任何帮助:)。

我正在使用的数据集是 body 的 3d .mhd 医学扫描。以下是在开始时将纹理添加到渲染器的方式:

for (int k = 0; k < NumberOfFrames; k++) {
    string fname_ = "T" + k.ToString("D2");
    Color[] colors = LoadData(Path.Combine (imageDir, fname_+".raw"));
    _volumeBuffer.Add (new Texture3D (dim [0], dim [1], dim [2], TextureFormat.RGBAHalf, mipmap));

    _volumeBuffer[k].SetPixels(colors);
    _volumeBuffer [k].Apply ();
}
GetComponent<Renderer>().material.SetTexture("_Data", _volumeBuffer[0]);

object 的大小是使用 mdh header 文件间距和体素尺寸定义的:

transform.localScale = new Vector3(mhdheader.spacing[0] * volScale, mhdheader.spacing[1] * volScale * dim[1] / dim[0], mhdheader.spacing[2] * volScale * dim[2] / dim[0]);

我尝试制作自己的函数,通过将索引偏移到渲染网格的开头来从世界中获取索引(不确定这是否正确)。然后,按局部比例缩放它。然后,乘以每个维度中的体素数量。但是,我不确定我的逻辑是否正确......这是我试过的代码:

public Vector3Int GetIndexFromWorld(Vector3 worldPos)
{
    Vector3 startOfTex = gameObject.GetComponent<Renderer>().bounds.min;
    Vector3 localPos = transform.InverseTransformPoint(worldPos);
    Vector3 localScale = gameObject.transform.localScale;
    Vector3 OffsetPos = localPos - startOfTex;

    Vector3 VoxelPosFloat = new Vector3(OffsetPos[0] / localScale[0], OffsetPos[1] / localScale[1], OffsetPos[2] / localScale[2]);
    VoxelPosFloat = Vector3.Scale(VoxelPosFloat, new Vector3(voxelDims[0], voxelDims[1], voxelDims[2]));
    Vector3Int voxelPos = Vector3Int.FloorToInt(VoxelPosFloat);
    return voxelPos;
}

您可以尝试设置大量的盒子碰撞器和每个碰撞器的 OnTriggerEnter() 函数 运行。但更好的解决方案是对体素数组进行排序,然后使用简单的数学运算将移动物体的位置向量固定为整数,并进行一些数学运算以将向量映射到数组中的索引。例如,向量 (0,0,0) 可以映射到体素 [0]。然后根据需要获取该体素属性。对于体素应用程序,这比碰撞器需要更快的计算。

我想我明白了。如果有人发现我的代码有任何缺陷,请告诉我:)。

public Vector3Int GetIndexFromWorld(Vector3 worldPos)
{
    Vector3 deltaBounds = rend.bounds.max - rend.bounds.min;
    Vector3 OffsetPos = worldPos - rend.bounds.min;
    Vector3 normPos = new Vector3(OffsetPos[0] / deltaBounds[0], OffsetPos[1] / deltaBounds[1], OffsetPos[2] / deltaBounds[2]);

    Vector3 voxelPositions = new Vector3(normPos[0] * voxelDims[0], normPos[1] * voxelDims[1], normPos[2] * voxelDims[2]);

    Vector3Int voxelPos = Vector3Int.FloorToInt(voxelPositions);
    return voxelPos;
}