【问题标题】:In unity, how do you find voxel information at a given worldspace position?在统一中,您如何在给定的世界空间位置找到体素信息?
【发布时间】:2021-03-12 23:41:55
【问题描述】:

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

我正在使用的数据集是身体的 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]);

对象的大小是通过使用 mdh 头文件间距以及体素尺寸来定义的:

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;
}

【问题讨论】:

  • 你已经尝试过什么?为什么它不起作用?
  • @Ruzihm 嗨,谢谢!我更新了问题以显示我已经尝试过的内容。

标签: unity3d transform voxel


【解决方案1】:

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

【讨论】:

  • 嗨!是的,谢谢你的评论。我编辑了我的问题以包含我尝试过的内容。
【解决方案2】:

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

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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-21
    相关资源
    最近更新 更多