/// <summary> /// Finds a set of predefined points on an edge. Normally it's only /// three - start, middle and end. If the edge type is "principal" /// and the target has a Collide.Shape, additional points at the surface /// of the shape may appear. /// </summary> /// <param name="edge">Edge to find predefined points on.</param> /// <returns>Iterator to point on the edge.</returns> private IEnumerable <Vector3> FindPredefinedEdgePoints(AGXUnity.Edge edge) { yield return(edge.Start); yield return(edge.Center); yield return(edge.End); if (edge.Type == AGXUnity.Edge.EdgeType.Triangle || m_collectedData == null || m_collectedData.Target == null || m_collectedData.Target.GetComponent <Shape>() == null) { yield break; } var utils = m_collectedData.Target.GetComponent <Shape>().GetUtils(); if (utils == null) { yield break; } var edgeDirections = ShapeUtils.ToDirection(ShapeUtils.ToPrincipal(utils.FindDirectionGivenWorldEdge(edge))); yield return(utils.GetWorldFace(edgeDirections[0])); yield return(utils.GetWorldFace(edgeDirections[1])); }
/// <summary> /// Finds closest edge to ray, including principal axes of the target object. /// </summary> /// <param name="ray">The ray.</param> /// <param name="triangleEdge">Triangle edge from raycast result.</param> /// <param name="principalEdgeExtension">Extension of principal axes relative to bounding box or object faces.</param> /// <returns>Edge (principal or triangle) closest to the given ray.</returns> private AGXUnity.Edge FindClosestEdgeIncludingTargetPrincipalAxes(Ray ray, AGXUnity.Edge triangleEdge, float principalEdgeExtension = 10.0f) { if (m_collectedData.Target == null) { return(new AGXUnity.Edge()); } var edges = new AGXUnity.Edge[4]; var shape = m_collectedData.Target.GetComponent <Shape>(); var shapeUtils = shape?.GetUtils(); if (shapeUtils != null) { Array.Copy(shapeUtils.GetPrincipalEdgesWorld(principalEdgeExtension), edges, 3); } else { var mesh = shape is AGXUnity.Collide.Mesh ? (shape as AGXUnity.Collide.Mesh).SourceObjects.FirstOrDefault() : m_collectedData.Target.GetComponent <MeshFilter>()?.sharedMesh; var halfExtents = 0.5f * Vector3.zero; if (mesh != null) { halfExtents = mesh.bounds.extents; } Array.Copy(ShapeUtils.ExtendAndTransformEdgesToWorld(m_collectedData.Target.transform, new AGXUnity.Edge[] { new AGXUnity.Edge() { Start = BoxShapeUtils.GetLocalFace(halfExtents, ShapeUtils.Direction.Negative_X), End = BoxShapeUtils.GetLocalFace(halfExtents, ShapeUtils.Direction.Positive_X), Normal = ShapeUtils.GetLocalFaceDirection(ShapeUtils.Direction.Positive_Y), Type = AGXUnity.Edge.EdgeType.Principal }, new AGXUnity.Edge() { Start = BoxShapeUtils.GetLocalFace(halfExtents, ShapeUtils.Direction.Negative_Y), End = BoxShapeUtils.GetLocalFace(halfExtents, ShapeUtils.Direction.Positive_Y), Normal = ShapeUtils.GetLocalFaceDirection(ShapeUtils.Direction.Positive_Z), Type = AGXUnity.Edge.EdgeType.Principal }, new AGXUnity.Edge() { Start = BoxShapeUtils.GetLocalFace(halfExtents, ShapeUtils.Direction.Negative_Z), End = BoxShapeUtils.GetLocalFace(halfExtents, ShapeUtils.Direction.Positive_Z), Normal = ShapeUtils.GetLocalFaceDirection(ShapeUtils.Direction.Positive_X), Type = AGXUnity.Edge.EdgeType.Principal } }, principalEdgeExtension), edges, 3); } edges[3] = triangleEdge; return(ShapeUtils.FindClosestEdgeToSegment(ray.origin, ray.GetPoint(5000.0f), edges).Edge); }
/// <summary> /// Finds point on edge given mouse ray. /// </summary> private Vector3 FindClosestPointOnEdge(AGXUnity.Edge edge) { var ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); return(ShapeUtils.ShortestDistanceSegmentSegment(ray.origin, ray.GetPoint(500f), edge.Start, edge.End).PointOnSegment2); }