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; }
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; }
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 }); }
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); }
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)); } }
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, }); }
public override bool ContainsPoint(Vector2 point) { return(TriangleMath.Contains2DPoint(point, BaseLeft, Tip, BaseRight)); }
public override bool ContainsPoint(Vector2 point) { var points = GetPoints(); return(TriangleMath.Contains2DPoint(point, points[0], points[1], points[2], _epsilon)); }
public List <Vector2> GetPoints() { return(TriangleMath.CalcRATriangle2DPoints(_rightAngleCorner, _XLength, _YLength, _rotationDegrees)); }
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); }
public bool ContainsPoint(Vector3 point, bool checkOnPlane) { List <Vector3> points = GetPoints(); return(TriangleMath.Contains3DPoint(point, checkOnPlane, points[0], points[1], points[2], _epsilon)); }
public List <Vector3> GetPoints() { return(TriangleMath.CalcRATriangle3DPoints(_rightAngleCorner, RealXLength, RealYLength, _rotation)); }
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)); }
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); }
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); } } }
public override bool ContainsPoint(Vector2 point) { return(TriangleMath.Contains2DPoint(point, GetPoint(EqTrianglePoint.Left), GetPoint(EqTrianglePoint.Top), GetPoint(EqTrianglePoint.Right), _epsilon)); }
/// <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); }
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)); }
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); } } }