Пример #1
0
        private void OnPointsFoundDirty()
        {
            System.Collections.Generic.List <Vector3> points = TriangleMath.CalcEqTriangle3DPoints(_centroid, _sideLength, _rotation);
            _points[(int)EqTrianglePoint.Left]  = points[(int)EqTrianglePoint.Left];
            _points[(int)EqTrianglePoint.Top]   = points[(int)EqTrianglePoint.Top];
            _points[(int)EqTrianglePoint.Right] = points[(int)EqTrianglePoint.Right];

            _arePointsDirty = false;
        }
Пример #2
0
        private void OnPointsFoundDirty()
        {
            List <Vector2> points = TriangleMath.CalcEqTriangle2DPoints(_centroid, _sideLength, Rotation);

            _points[(int)EqTrianglePoint.Left]  = points[(int)EqTrianglePoint.Left];
            _points[(int)EqTrianglePoint.Top]   = points[(int)EqTrianglePoint.Top];
            _points[(int)EqTrianglePoint.Right] = points[(int)EqTrianglePoint.Right];

            _arePointsDirty = false;
        }
Пример #3
0
        public static List <Vector3> CalcEqTriangle3DPoints(Vector3 centroid, float sideLength, Quaternion rotation)
        {
            float   halfSideLength   = sideLength * 0.5f;
            float   centroidAltitude = TriangleMath.GetEqTriangleCentroidAltitude(sideLength);
            Vector3 midLeftRight     = centroid - rotation * Vector3.up * centroidAltitude;

            return(new List <Vector3>()
            {
                midLeftRight - rotation * Vector3.right * halfSideLength,
                centroid + rotation * Vector3.up * (TriangleMath.GetEqTriangleAltitude(sideLength) - centroidAltitude),
                midLeftRight + rotation * Vector3.right * halfSideLength
            });
        }
Пример #4
0
        public static Mesh CreateWireEqXY(Vector3 centroid, float sideLength, Color color)
        {
            Vector3[] positions = TriangleMath.CalcEqTriangle3DPoints(centroid, sideLength, Quaternion.identity).ToArray();

            Mesh mesh = new Mesh();

            mesh.vertices = positions;
            mesh.colors   = new Color[] { color, color, color };
            mesh.SetIndices(new int[] { 0, 1, 2, 0 }, MeshTopology.LineStrip, 0);
            mesh.UploadMeshData(false);

            return(mesh);
        }
Пример #5
0
        public override bool Raycast(Ray ray, out float t)
        {
            List <Vector3> trianglePoints = GetPoints();

            if (_raycastMode == Shape3DRaycastMode.Solid)
            {
                return(TriangleMath.Raycast(ray, out t, trianglePoints[0], trianglePoints[1], trianglePoints[2], _epsilon));
            }
            else
            {
                return(TriangleMath.RaycastWire(ray, out t, trianglePoints[0], trianglePoints[1], trianglePoints[2], _epsilon));
            }
        }
Пример #6
0
        public static List <Vector2> CalcEqTriangle2DPoints(Vector2 centroid, float sideLength, Quaternion rotation)
        {
            float halfSideLength   = sideLength * 0.5f;
            float centroidAltitude = TriangleMath.GetEqTriangleCentroidAltitude(sideLength);

            Vector2 triangleRight = rotation * Vector2.right;
            Vector2 triangleUp    = rotation * Vector2.up;
            Vector2 midLeftRight  = centroid - triangleUp * centroidAltitude;

            return(new List <Vector2>()
            {
                midLeftRight - triangleRight * halfSideLength,
                centroid + triangleUp * (TriangleMath.GetEqTriangleAltitude(sideLength) - centroidAltitude),
                midLeftRight + triangleRight * halfSideLength,
            });
        }
Пример #7
0
 public override bool ContainsPoint(Vector2 point)
 {
     return(TriangleMath.Contains2DPoint(point, BaseLeft, Tip, BaseRight));
 }
Пример #8
0
        public override bool ContainsPoint(Vector2 point)
        {
            var points = GetPoints();

            return(TriangleMath.Contains2DPoint(point, points[0], points[1], points[2], _epsilon));
        }
Пример #9
0
 public List <Vector2> GetPoints()
 {
     return(TriangleMath.CalcRATriangle2DPoints(_rightAngleCorner, _XLength, _YLength, _rotationDegrees));
 }
Пример #10
0
        public static bool Raycast(Ray ray, out float t, Vector3 baseCenter, float baseWidth, float baseDepth, float height, Quaternion rotation)
        {
            t   = 0.0f;
            ray = ray.InverseTransform(Matrix4x4.TRS(baseCenter, rotation, Vector3.one));

            Vector3 aabbSize = new Vector3(baseWidth, height, baseDepth);

            if (!BoxMath.Raycast(ray, Vector3.up * height * 0.5f, aabbSize, Quaternion.identity))
            {
                return(false);
            }

            List <float> tValues = new List <float>(5);

            Plane basePlane = new Plane(Vector3.up, Vector3.zero);
            float rayEnter  = 0.0f;

            if (basePlane.Raycast(ray, out rayEnter) &&
                QuadMath.Contains3DPoint(ray.GetPoint(rayEnter), false, baseCenter, baseWidth, baseDepth, Vector3.right, Vector3.forward))
            {
                tValues.Add(rayEnter);
            }

            float   halfWidth     = 0.5f * baseWidth;
            float   halfDepth     = 0.5f * baseDepth;
            Vector3 tipPosition   = Vector3.up * height;
            Vector3 p0            = tipPosition;
            Vector3 p1            = Vector3.right * halfWidth - Vector3.forward * halfDepth;
            Vector3 p2            = p1 - Vector3.right * baseWidth;
            Plane   trianglePlane = new Plane(p0, p1, p2);

            if (trianglePlane.Raycast(ray, out rayEnter) &&
                TriangleMath.Contains3DPoint(ray.GetPoint(rayEnter), false, p0, p1, p2))
            {
                tValues.Add(rayEnter);
            }

            p0            = tipPosition;
            p1            = Vector3.right * halfWidth + Vector3.forward * halfDepth;
            p2            = p1 - Vector3.forward * baseDepth;
            trianglePlane = new Plane(p0, p1, p2);
            if (trianglePlane.Raycast(ray, out rayEnter) &&
                TriangleMath.Contains3DPoint(ray.GetPoint(rayEnter), false, p0, p1, p2))
            {
                tValues.Add(rayEnter);
            }

            p0            = tipPosition;
            p1            = -Vector3.right * halfWidth + Vector3.forward * halfDepth;
            p2            = p1 + Vector3.right * baseWidth;
            trianglePlane = new Plane(p0, p1, p2);
            if (trianglePlane.Raycast(ray, out rayEnter) &&
                TriangleMath.Contains3DPoint(ray.GetPoint(rayEnter), false, p0, p1, p2))
            {
                tValues.Add(rayEnter);
            }

            p0            = tipPosition;
            p1            = -Vector3.right * halfWidth - Vector3.forward * halfDepth;
            p2            = p1 + Vector3.forward * baseDepth;
            trianglePlane = new Plane(p0, p1, p2);
            if (trianglePlane.Raycast(ray, out rayEnter) &&
                TriangleMath.Contains3DPoint(ray.GetPoint(rayEnter), false, p0, p1, p2))
            {
                tValues.Add(rayEnter);
            }

            if (tValues.Count == 0)
            {
                return(false);
            }

            tValues.Sort(delegate(float t0, float t1) { return(t0.CompareTo(t1)); });
            t = tValues[0];

            return(true);
        }
Пример #11
0
        public bool ContainsPoint(Vector3 point, bool checkOnPlane)
        {
            List <Vector3> points = GetPoints();

            return(TriangleMath.Contains3DPoint(point, checkOnPlane, points[0], points[1], points[2], _epsilon));
        }
Пример #12
0
 public List <Vector3> GetPoints()
 {
     return(TriangleMath.CalcRATriangle3DPoints(_rightAngleCorner, RealXLength, RealYLength, _rotation));
 }
Пример #13
0
        public override bool RaycastWire(Ray ray, out float t)
        {
            List <Vector3> trianglePoints = GetPoints();

            return(TriangleMath.RaycastWire(ray, out t, trianglePoints[0], trianglePoints[1], trianglePoints[2], _epsilon));
        }
Пример #14
0
        public static bool RaycastTriangular(Ray ray, out float t, Vector3 baseCenter,
                                             float baseWidth, float baseDepth, float topWidth, float topDepth, float height, Quaternion prismRotation)
        {
            t = 0.0f;
            if (baseWidth == 0.0f || baseDepth == 0.0f ||
                topWidth == 0.0f || topDepth == 0.0f || height == 0.0f)
            {
                return(false);
            }

            baseWidth = Mathf.Abs(baseWidth);
            baseDepth = Mathf.Abs(baseDepth);
            topWidth  = Mathf.Abs(topWidth);
            topDepth  = Mathf.Abs(topDepth);

            ray = ray.InverseTransform(Matrix4x4.TRS(baseCenter, prismRotation, Vector3.one));

            // Since the raycast calculations can be quite expensive for a prism, we will
            // first check if the ray intersects its AABB to quickly return false if no
            // intersection is found. If the ray does not intersect the AABB it can not
            // possibly intersect the prism.
            Vector3 aabbSize = Vector3.Max(new Vector3(baseWidth, height, baseDepth), new Vector3(topWidth, height, topDepth));

            if (!BoxMath.Raycast(ray, Vector3.up * height * 0.5f, aabbSize, Quaternion.identity))
            {
                return(false);
            }

            List <Vector3> cornerPoints  = CalcTriangPrismCornerPoints(Vector3.zero, baseWidth, baseDepth, topWidth, topDepth, height, Quaternion.identity);
            Vector3        baseLeftPt    = cornerPoints[(int)TriangularPrismCorner.BaseLeft];
            Vector3        baseRightPt   = cornerPoints[(int)TriangularPrismCorner.BaseRight];
            Vector3        baseForwardPt = cornerPoints[(int)TriangularPrismCorner.BaseForward];

            Vector3 topLeftPt    = cornerPoints[(int)TriangularPrismCorner.TopLeft];
            Vector3 topRightPt   = cornerPoints[(int)TriangularPrismCorner.TopRight];
            Vector3 topForwardPt = cornerPoints[(int)TriangularPrismCorner.TopForward];

            List <float> tValues = new List <float>(5);

            // Base triangle
            float rayEnter;

            if (TriangleMath.Raycast(ray, out rayEnter, baseLeftPt, baseRightPt, baseForwardPt))
            {
                tValues.Add(rayEnter);
            }

            // Top triangle
            if (TriangleMath.Raycast(ray, out rayEnter, topLeftPt, topForwardPt, topRightPt))
            {
                tValues.Add(rayEnter);
            }

            // Back face
            List <Vector3> facePoints = new List <Vector3>(4)
            {
                baseLeftPt, topLeftPt, topRightPt, baseRightPt
            };
            Vector3 faceNormal = Vector3.Cross((facePoints[1] - facePoints[0]), facePoints[3] - facePoints[0]).normalized;

            if (PolygonMath.Raycast(ray, out rayEnter, facePoints, false, faceNormal))
            {
                tValues.Add(rayEnter);
            }

            // Left face
            // facePoints[0] = baseLeftPt;
            facePoints[1] = baseForwardPt;
            facePoints[2] = topForwardPt;
            facePoints[3] = topLeftPt;
            faceNormal    = Vector3.Cross((facePoints[1] - facePoints[0]), facePoints[3] - facePoints[0]).normalized;
            if (PolygonMath.Raycast(ray, out rayEnter, facePoints, false, faceNormal))
            {
                tValues.Add(rayEnter);
            }

            // Right face
            facePoints[0] = baseRightPt;
            facePoints[1] = topRightPt;
            // facePoints[2] = topForwardPt;
            facePoints[3] = baseForwardPt;
            faceNormal    = Vector3.Cross((facePoints[1] - facePoints[0]), facePoints[3] - facePoints[0]).normalized;
            if (PolygonMath.Raycast(ray, out rayEnter, facePoints, false, faceNormal))
            {
                tValues.Add(rayEnter);
            }

            if (tValues.Count == 0)
            {
                return(false);
            }

            tValues.Sort(delegate(float t0, float t1) { return(t0.CompareTo(t1)); });
            t = tValues[0];

            return(true);
        }
Пример #15
0
        private void OnGizmoAttemptHandleDragBegin(Gizmo gizmo, int handleId)
        {
            if (handleId == HandleId)
            {
                if (_dragChannel == GizmoDragChannel.Offset)
                {
                    GizmoDblAxisOffsetDrag3D.WorkData workData = new GizmoDblAxisOffsetDrag3D.WorkData();
                    workData.Axis0      = Vector2Ex.ConvertDirTo3D(_transform.Right2D, OffsetDragOrigin, Gizmo.FocusCamera).normalized;
                    workData.Axis1      = Vector2Ex.ConvertDirTo3D(_transform.Up2D, OffsetDragOrigin, Gizmo.FocusCamera).normalized;
                    workData.DragOrigin = OffsetDragOrigin;
                    workData.SnapStep0  = Settings.OffsetSnapStepRight;
                    workData.SnapStep1  = Settings.OffsetSnapStepUp;
                    _offsetDrag.SetWorkData(workData);
                }
                else
                if (_dragChannel == GizmoDragChannel.Rotation)
                {
                    GizmoSglAxisRotationDrag3D.WorkData workData = new GizmoSglAxisRotationDrag3D.WorkData();
                    workData.Axis     = Gizmo.FocusCamera.transform.forward;
                    workData.SnapMode = Settings.RotationSnapMode;
                    workData.SnapStep = Settings.RotationSnapStep;
                    if (LookAndFeel.PlaneType != GizmoPlane2DType.Polygon)
                    {
                        workData.RotationPlanePos = Gizmo.FocusCamera.ScreenToWorldPoint(new Vector3(Position.x, Position.y, Gizmo.FocusCamera.nearClipPlane));
                    }

                    if (LookAndFeel.PlaneType == GizmoPlane2DType.Circle)
                    {
                        _rotationArc.SetArcData(Position, Gizmo.HoverInfo.HoverPoint, GetRealCircleRadius());
                        _rotationArc.Type = GizmoRotationArc2D.ArcType.Standard;
                    }
                    else
                    if (LookAndFeel.PlaneType == GizmoPlane2DType.Polygon)
                    {
                        Vector3 polyCenter = PolyCenter;
                        workData.RotationPlanePos = Gizmo.FocusCamera.ScreenToWorldPoint(new Vector3(polyCenter.x, polyCenter.y, Gizmo.FocusCamera.nearClipPlane));
                        _rotationArc.SetArcData(PolyCenter, Gizmo.HoverInfo.HoverPoint, 1.0f);
                        _rotationArc.Type               = GizmoRotationArc2D.ArcType.PolyProjected;
                        _rotationArc.ProjectionPoly     = _polygon;
                        _rotationArc.NumProjectedPoints = 100;
                    }
                    _rotationDrag.SetWorkData(workData);
                }
                else
                if (_dragChannel == GizmoDragChannel.Scale)
                {
                    _scaleAxisRight = Vector2Ex.ConvertDirTo3D(Position, GetRealExtentPoint(Shape2DExtentPoint.Right), ScaleDragOrigin, Gizmo.FocusCamera);
                    _scaleAxisUp    = Vector2Ex.ConvertDirTo3D(Position, GetRealExtentPoint(Shape2DExtentPoint.Top), ScaleDragOrigin, Gizmo.FocusCamera);

                    GizmoDblAxisScaleDrag3D.WorkData workData = new GizmoDblAxisScaleDrag3D.WorkData();
                    workData.Axis0        = _scaleAxisRight.normalized;
                    workData.Axis1        = _scaleAxisUp.normalized;
                    workData.AxisIndex0   = _scaleDragAxisIndexRight;
                    workData.AxisIndex1   = _scaleDragAxisIndexUp;
                    workData.DragOrigin   = ScaleDragOrigin;
                    workData.ScaleMode    = Settings.ScaleMode;
                    workData.IndBaseSize0 = _scaleAxisRight.magnitude;
                    workData.IndBaseSize1 = _scaleAxisUp.magnitude;

                    if (workData.ScaleMode == GizmoDblAxisScaleMode.Independent)
                    {
                        workData.IndSnapStep0 = Settings.ScaleSnapStepRight;
                        workData.IndSnapStep1 = Settings.ScaleSnapStepUp;
                        workData.IndBaseSize0 = _scaleAxisRight.magnitude;
                        workData.IndBaseSize1 = _scaleAxisUp.magnitude;
                    }
                    else
                    {
                        Vector2 triSides = new Vector2(_scaleAxisRight.magnitude, _scaleAxisUp.magnitude);
                        workData.PropBaseSize = TriangleMath.CalcRATriangleHypotenuse(triSides);
                        workData.PropSnapStep = Settings.ProportionalScaleSnapStep;
                        workData.PropAxis     = ((Right + Up) * 0.5f).normalized;
                    }

                    _scaleDrag.SetWorkData(workData);
                }
            }
        }
Пример #16
0
 public override bool ContainsPoint(Vector2 point)
 {
     return(TriangleMath.Contains2DPoint(point, GetPoint(EqTrianglePoint.Left), GetPoint(EqTrianglePoint.Top), GetPoint(EqTrianglePoint.Right), _epsilon));
 }
Пример #17
0
        /// <summary>
        /// Performs a raycast against the mesh triangles and returns info
        /// about the closest hit or null if no triangle was hit by the ray.
        /// </summary>
        /// <param name="meshTransform">
        /// The mesh transform which brings the mesh in the same space as the
        /// ray.
        /// </param>
        /// <remarks>
        /// This method will build the tree if it hasn't already been built.
        /// </remarks>
        public MeshRayHit RaycastClosest(Ray ray, Matrix4x4 meshTransform)
        {
            // Build the tree if it hasn't already been built
            if (!_isBuilt)
            {
                Build();
            }

            // Work in mesh local space by transforming the ray by the inverse of
            // the mesh transform. It is faster to perform this transformation here
            // instead of transforming every possibly hit triangle by 'meshTransform'.
            Ray modelSpaceRay = ray.InverseTransform(meshTransform);

            // Get the list of tree nodes which are hit by the ray
            List <SphereTreeNodeRayHit <MeshTriangle> > nodeHits = _tree.RaycastAll(modelSpaceRay);

            if (nodeHits.Count == 0)
            {
                return(null);
            }

            // Store data in preparation for closest hit identification
            float        t;
            float        minT            = float.MaxValue;
            MeshTriangle closestTriangle = null;
            bool         foundTriangle   = false;

            // Loop through each node hit
            foreach (SphereTreeNodeRayHit <MeshTriangle> nodeHit in nodeHits)
            {
                // Get the associated mesh triangle and check if the ray intersects it
                MeshTriangle meshTriangle = nodeHit.HitNode.Data;
                if (TriangleMath.Raycast(modelSpaceRay, out t, meshTriangle.Vertex0, meshTriangle.Vertex1, meshTriangle.Vertex2))
                {
                    if (Vector3.Dot(modelSpaceRay.direction, meshTriangle.Normal) < 0.0f)
                    {
                        // If the intersection offset is smaller than what we have so far,
                        // it means we have a new closest hit.
                        if (t < minT)
                        {
                            minT            = t;
                            closestTriangle = meshTriangle;
                            foundTriangle   = true;
                        }
                    }
                }
            }

            // If we found a triangle, we can return the mesh ray hit information
            if (foundTriangle)
            {
                // Convert the t value in world space. Do the same for the normal.
                Vector3 worldHit = meshTransform.MultiplyPoint(modelSpaceRay.GetPoint(minT));
                minT = (ray.origin - worldHit).magnitude / ray.direction.magnitude;
                Vector3 transformedNormal = meshTransform.inverse.transpose.MultiplyVector(closestTriangle.Normal).normalized;

                // Return the hit instance
                return(new MeshRayHit(ray, closestTriangle.TriangleIndex, minT, transformedNormal));
            }

            return(null);
        }
Пример #18
0
 public override bool RaycastWire(Ray ray, out float t)
 {
     return(TriangleMath.RaycastWire(ray, out t, GetPoint(EqTrianglePoint.Left), GetPoint(EqTrianglePoint.Top), GetPoint(EqTrianglePoint.Right), _epsilon));
 }
Пример #19
0
        private void OnGizmoAttemptHandleDragBegin(Gizmo gizmo, int handleId)
        {
            if (handleId == HandleId)
            {
                if (_dragChannel == GizmoDragChannel.Offset)
                {
                    GizmoDblAxisOffsetDrag3D.WorkData workData = new GizmoDblAxisOffsetDrag3D.WorkData();
                    workData.Axis0      = Right;
                    workData.Axis1      = Up;
                    workData.DragOrigin = Position;
                    workData.SnapStep0  = Settings.OffsetSnapStepRight;
                    workData.SnapStep1  = Settings.OffsetSnapStepUp;
                    _dblAxisOffsetDrag.SetWorkData(workData);
                }
                else
                if (_dragChannel == GizmoDragChannel.Rotation)
                {
                    GizmoSglAxisRotationDrag3D.WorkData workData = new GizmoSglAxisRotationDrag3D.WorkData();
                    workData.Axis             = Normal;
                    workData.RotationPlanePos = Position;
                    workData.SnapMode         = Settings.RotationSnapMode;
                    workData.SnapStep         = Settings.RotationSnapStep;
                    _rotationDrag.SetWorkData(workData);

                    Vector3 arcStart = Plane.ProjectPoint(Gizmo.HoverInfo.HoverPoint);
                    _rotationArc.SetArcData(Normal, Position, arcStart, GetRealCircleRadius(GetZoomFactor(Gizmo.FocusCamera)));
                }
                else
                if (_dragChannel == GizmoDragChannel.Scale)
                {
                    float zoomFactor = GetZoomFactor(Gizmo.FocusCamera);

                    GizmoDblAxisScaleDrag3D.WorkData workData = new GizmoDblAxisScaleDrag3D.WorkData();
                    workData.Axis0      = Right;
                    workData.Axis1      = Up;
                    workData.DragOrigin = Position;
                    workData.AxisIndex0 = _scaleDragAxisIndexRight;
                    workData.AxisIndex1 = _scaleDragAxisIndexUp;
                    workData.ScaleMode  = Settings.ScaleMode;

                    if (workData.ScaleMode == GizmoDblAxisScaleMode.Independent)
                    {
                        workData.IndSnapStep0 = Settings.ScaleSnapStepRight;
                        workData.IndSnapStep1 = Settings.ScaleSnapStepUp;

                        if (LookAndFeel.PlaneType == GizmoPlane3DType.Quad)
                        {
                            workData.IndBaseSize0 = GetRealQuadWidth(zoomFactor) * 0.5f;
                            workData.IndBaseSize1 = GetRealQuadHeight(zoomFactor) * 0.5f;
                        }
                        else
                        if (LookAndFeel.PlaneType == GizmoPlane3DType.RATriangle)
                        {
                            workData.IndBaseSize0 = GetRealRATriXLength(zoomFactor);
                            workData.IndBaseSize1 = GetRealRATriYLength(zoomFactor);
                        }
                    }
                    else
                    {
                        if (LookAndFeel.PlaneType == GizmoPlane3DType.Quad)
                        {
                            workData.PropBaseSize = TriangleMath.CalcRATriangleHypotenuse(GetRealQuadSize(zoomFactor) * 0.5f);
                        }
                        else
                        if (LookAndFeel.PlaneType == GizmoPlane3DType.RATriangle)
                        {
                            workData.PropBaseSize = TriangleMath.CalcRATriangleAltitude(GetRealRATriSize(zoomFactor));
                        }

                        workData.PropSnapStep = Settings.ProportionalScaleSnapStep;
                        workData.PropAxis     = ((Right + Up) * 0.5f).normalized;
                    }

                    _scaleDrag.SetWorkData(workData);
                }
            }
        }