Расчет пересечения сетки не работает на повернутых объектах - PullRequest
0 голосов
/ 27 сентября 2019

Я работаю над инструментом для создания небольших зданий, основанным на игровом движке Unity3D.В этом инструменте я хочу иметь возможность разместить дымоходы на крыше.Чтобы проверить, находится ли мой дымоход на крыше во время процесса установки, я хочу отправить пучок лучей из вершин дна сетки дымохода.Так как крышу можно наклонить и дымоход должен быть выровнен с крышей, я не могу проверить ровное дно дымохода.Чтобы быть обнаруживаемым для системы столкновений с единым целым, я должен послать свои лучи снаружи коллайдера сетки.Для этого я хочу выполнить «виртуальный разрез сетки», где я перевожу нижние вершины сетки дымоходов, чтобы они соответствовали наклону крыши.Пока все хорошо.

Мое текущее решение основано на идее, что центр основания сетки дымохода, вершина, которую я хочу перевести, и новое положение вершины описывают треугольник.Так как у меня есть нормаль крыши и две точки треугольника (нижний центр сетки и начало вершины), я вычисляю Y-координату третьей точки для каждой вершины, например:

 public static Vector3[] GetVirtualMeshCutVertices(IEnumerable<Vector3> vertices, Vector3 normal)
        {
            bool xAxisAligned = Math.Abs(normal.z) < Math.Abs(normal.x);

            float degreeAngle = (xAxisAligned ? normal.x : normal.z) > 0
                ? Vector3.Angle(Vector3.up, normal)
                : 180 - Vector3.Angle(Vector3.up, normal);

            double surfaceAngle = degreeAngle * Math.PI / 180;
            double surfaceAngleSin = Math.Sin(surfaceAngle);
            double surfaceAngleCos = Math.Cos(surfaceAngle);

            return vertices.Select(vector3 =>
                GetNewVertexPoint(Vector3.zero, vector3, surfaceAngleCos, surfaceAngleSin, xAxisAligned)).ToArray();
        }

        private static Vector3 GetNewVertexPoint(Vector3 origin, Vector3 oldVertexPoint, double angleCos,
                                                 double angleSin, bool xAxisAligned)
        {
            var originVec2 = new Vector2(xAxisAligned ? origin.x : origin.z, origin.y);
            var oldVertex = new Vector2(xAxisAligned ? oldVertexPoint.x : oldVertexPoint.z, oldVertexPoint.y);

            double newYValue = oldVertex.y + (originVec2.x - oldVertex.x) / angleCos * angleSin;

            return new Vector3(oldVertexPoint.x, (float) newYValue, oldVertexPoint.z);
        }

Как вы, вероятно, видите, это решение напрямую украдено из 2D-пространства.И это прекрасно работает, если крыши выровнены по оси X или Z.Но как только я поворачиваю их, конструкция разваливается.

Затем я попытался повернуть вершины, чтобы они соответствовали нормали крыши, и подумал о других формулах, чтобы получить «новую точку вершины».Пока безуспешно ...

Так что, возможно, у вас есть идея, как привести эту формулу в трехмерное пространство, или у вас есть совершенно новое решение для моей проблемы.Заранее спасибо:)

...