Physics.Raycast 无法使用 Marching Cubes 生成的网格

Physics.Raycast not working with a Marching Cubes -generated mesh

What it spits out

我的 raycast 吐出了一个偏离它应该的位置的位置。我正在尝试以程序方式将对象放置在程序网格上。一段时间以来,我一直在摸不着头脑。请帮忙。 抱歉,脚本太长了。

代码的开头只是一些声明和内容。 Start 完成后,GenObjects 在 FixedUpdate 中是 运行 一次。我正在使用 marching cubes library by Scrawk and a noise library by Auburn

    void GenMesh()
    {
        Marching marching = new MarchingCubes();
        marching.Surface = 0.0f;
        voxels = new float[width * height * length];

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                for (int z = 0; z < length; z++)
                {
                    float fx = x / (width - 1.0f);
                    float fy = y / (height - 1.0f);
                    float fz = z / (length - 1.0f);

                    int idx = x + y * width + z * width * height;


                    float surfaceHeight = noise2.GetNoise(x,z) * amplitude + offset;
                    float currentHeight = Mathf.Clamp(y, surfaceHeight - threshold, surfaceHeight + threshold);
                    float t = Mathf.Abs(currentHeight - surfaceHeight) / threshold;
                    voxels[idx] = Mathf.Lerp(Mathf.Clamp(noise.GetNoise(x,y,z), 0.65f, 1), -1f, t);
                }
            }
        }
        List<Vector3> verts = new List<Vector3>();
        List<int> indices = new List<int>();
        marching.Generate(voxels, width, height, length, verts, indices);
        int maxVertsPerMesh = 30000;
        int numMeshes = verts.Count / maxVertsPerMesh + 1;

        for (int i = 0; i < numMeshes; i++)
        {

            List<Vector3> splitVerts = new List<Vector3>();
            List<int> splitIndices = new List<int>();

            for (int j = 0; j < maxVertsPerMesh; j++)
            {
                int idx = i * maxVertsPerMesh + j;

                if (idx < verts.Count)
                {
                    splitVerts.Add(verts[idx]);
                    splitIndices.Add(j);
                }
            }

            if (splitVerts.Count == 0) continue;

            Mesh mesh = new Mesh();
            mesh.SetVertices(splitVerts);
            mesh.SetTriangles(splitIndices, 0);
            mesh.RecalculateBounds();
            mesh.RecalculateNormals();

            MeshWelder meshWelder = new MeshWelder(mesh);
            meshWelder.Weld();

            GameObject go = new GameObject("Mesh");
            go.layer = LayerMask.NameToLayer("Ground");
            go.transform.parent = transform;
            go.transform.localScale = new Vector3(100f, 100f, 100f);
            go.AddComponent<MeshFilter>();
            go.AddComponent<MeshRenderer>();
            go.AddComponent<MeshCollider>();
            go.GetComponent<Renderer>().material = m_material;
            go.GetComponent<MeshFilter>().mesh = mesh;
            go.GetComponent<MeshCollider>().sharedMesh = mesh;
            go.GetComponent<MeshCollider>().contactOffset = 0f;
            go.transform.localPosition = new Vector3(-width * 100 / 2, -height * 100 / 4, -length * 100 / 2);

            meshes.Add(go);
        }
    }

    void GenObjects(GameObject prefab, float radius, Vector2 sampleRegionSize, Vector2 origin, int seed)
    {
        List<Vector2> points = PoissonDiscSampling.GeneratePoints(radius, sampleRegionSize, seed);
        Physics.queriesHitBackfaces = true;
        foreach (Vector2 point in points)
        {
            RaycastHit hit;
            Vector3 objPos = new Vector3(0,0,0);
            bool validPosFound = false;
            if (Physics.Raycast(new Vector3(point.x + origin.x, 0, point.y + origin.y), Vector3.down, out hit, height * 100, layerMask))
            {
                objPos = hit.point;
                validPosFound = true;
            } else if (Physics.Raycast(new Vector3(point.x + origin.x, 0, point.y + origin.y), Vector3.up, out hit, height * 100, layerMask))
            {
                objPos = hit.point;
                validPosFound = true;
            }
            if (validPosFound)
            {
                GameObject newObject = Instantiate(prefab, objPos, Quaternion.Euler(0, 0, 0));
            }
        }
        Physics.queriesHitBackfaces = false;
    }
}

已修复!我的错误真的很愚蠢。我没有分配焊接网格,留下了一个肮脏的网格,上面漂浮着许多空顶点。光线投射击中了他们。

有心人的固话:

            Mesh mesh = new Mesh();
            Mesh mesh_temp = new Mesh();

            mesh_temp.SetVertices(splitVerts);
            mesh_temp.SetTriangles(splitIndices, 0);
            mesh_temp.RecalculateBounds();
            mesh_temp.RecalculateNormals();

            MeshWelder meshWelder = new MeshWelder();
            meshWelder.customMesh = new CustomMesh();
            meshWelder.customMesh.vertices = splitVerts.ToArray();
            meshWelder.customMesh.triangles = splitIndices.ToArray();
            meshWelder.customMesh.normals = mesh_temp.normals;
            meshWelder.Weld();

            mesh.SetVertices(meshWelder.customMesh.vertices);
            mesh.SetTriangles(meshWelder.customMesh.triangles, 0);
            mesh.SetNormals(meshWelder.customMesh.normals);
            mesh.RecalculateBounds();