不正确的方块被光线投射时从网格中移除

问题描述 投票:0回答:0

我已经实施了一个方形移除,以移除两个创建正方形的三角形,它有时会作为一个正方形移除,但问题是它移除的是错误的,而不是被光线投射击中的那个。

我分享了下面的截图和代码: Here I am trying to remove the square that my cube is facing, but it is removing the one on the side

代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RemoveSquare : MonoBehaviour
{
    [SerializeField] private SkinnedMeshRenderer meshRenderer;
    [SerializeField] private Transform selectOrigin;
    [SerializeField] [Range(0.1f, 20.0f)] private float maxDistance = 10f;
    private Mesh originalMesh;
    private Mesh mesh;
    private HashSet<int> squaresToRemove = new HashSet<int>();

    private void Start()
    {
        originalMesh = meshRenderer.sharedMesh;
        mesh = Instantiate(originalMesh);
    }

    private void Update()
    {
        DeleteSquare();
    }

    private void DeleteSquare()
    {
        Ray ray = new Ray(selectOrigin.position, selectOrigin.forward);

        if (Input.GetKeyDown(KeyCode.C))
        {
            if (Physics.Raycast(ray, out RaycastHit hit, maxDistance))
            {
                //Draw a line from object to origin
                Debug.DrawLine(selectOrigin.position, hit.point, Color.red, 1f);
                // Check if the hit object is the same as this object
                if (hit.transform == transform)
                {
                    int[] triangles = mesh.triangles;
                    int hitTriangleIndex = hit.triangleIndex;

                    // Add the hit triangle index to the set of triangles to remove
                    squaresToRemove.Clear();
                    squaresToRemove.Add(hitTriangleIndex);

                    // Find the squares that belong to the triangles to remove
                    foreach (int triangleIndex in new HashSet<int>(squaresToRemove))
                    {
                        int[] triangleVertices = new int[3];
                        triangleVertices[0] = triangles[triangleIndex * 3];
                        triangleVertices[1] = triangles[triangleIndex * 3 + 1];
                        triangleVertices[2] = triangles[triangleIndex * 3 + 2];

                        // Find the triangles that share an edge with the current triangle and add them to the removal list
                        for (int i = 0; i < triangles.Length / 3; i++)
                        {
                            if (i == triangleIndex && IsEdgeShared(triangleVertices, triangleVertices, triangleVertices, triangleVertices))
                            {
                                continue;
                            }

                            int[] compareVertices = new int[3];
                            compareVertices[0] = triangles[i * 3];
                            compareVertices[1] = triangles[i * 3 + 1];
                            compareVertices[2] = triangles[i * 3 + 2];

                            int matches = 0;
                            for (int j = 0; j < 3; j++)
                            {
                                if (((IList)triangleVertices).Contains(compareVertices[j]))
                                {
                                    matches++;
                                }
                            }

                            if (matches == 2)
                            {
                                squaresToRemove.Add(i);
                                break;
                            }
                        }
                    }

                    // Remove the triangles in the removal list
                    List<int> newTriangles = new List<int>();
                    for (int i = 0; i < triangles.Length; i += 3)
                    {
                        if (!squaresToRemove.Contains(i / 3))
                        {
                            newTriangles.Add(triangles[i]);
                            newTriangles.Add(triangles[i + 1]);
                            newTriangles.Add(triangles[i + 2]);
                        }
                    }

                    // Update the mesh triangles and recalculate normals and tangents
                    mesh.triangles = newTriangles.ToArray();
                    mesh.RecalculateNormals();
                    mesh.RecalculateTangents();
                    meshRenderer.sharedMesh = mesh;

                    // Show confirmation message
                    Debug.Log("Squares removed: " + squaresToRemove.Count);
                }
            }
        }
    }
    
    // Check if two triangles share an edge and vertex that is only cornered by the two  triangles from point a and c to point b and d respectively
    private bool IsEdgeShared(int[] a, int[] b, int[] c, int[] d)
    {
        int matches = 0;
        for (int i = 0; i < 3; i++)
        {
            if (((IList)a).Contains(b[i]))
            {
                matches++;
            }
        }

        if (matches == 2)
        {
            return true;
        }

        matches = 0;
        for (int i = 0; i < 3; i++)
        {
            if (((IList)c).Contains(d[i]))
            {
                matches++;
            }
        }

        if (matches == 2)
        {
            return true;
        }

        return false;
    }

}
c# unity3d mesh raycasting triangle
© www.soinside.com 2019 - 2024. All rights reserved.