public bool Calculate(IModel model) { // Counts ray-triangle intersections with an arbitrary ray direction. // If intersection count is odd, the point is inside. // Can return incorrect value in certain edge cases (when the ray casted touches a single triangle). var intersectNum = 0; var rayDir = _point + new Vector3(0.1f, 0, 0); var vertexList = new List <Vertex>(); //TODO: Slow implementation. Room for improvement with broad-phase prefiltering, e.g. AABB-based. foreach (var faceVertices in model.GetFaceVertices(model.Faces, vertexList)) { foreach (var tri in _triangulator.Triangulate(vertexList)) { if (RayIntersectsTriangle(_point, rayDir, tri, out var intersectPoint)) { // Count only new intersection points, since intersection point can touch the edge of two triangles, or a vertex of multiple triangles. if (_intersectionPoints.Add(intersectPoint)) { intersectNum++; } } } } _intersectionPoints.Clear(); return(intersectNum % 2 == 1); }
/// <summary> Triangulates a polygon, applying quality and constraint options. </summary> /// <param name="polygon">Polygon.</param> /// <param name="options">Constraint options.</param> /// <param name="quality">Quality options.</param> /// <param name="triangulator">The triangulation algorithm.</param> public static Mesh Triangulate(this Polygon polygon, ConstraintOptions options, QualityOptions quality, ITriangulator triangulator) { return(triangulator .Triangulate(polygon.Points) .ApplyConstraints(polygon, options, quality)); }
public void Triangulate(ITriangulator triangulator) { Debug.Assert(spriteMeshData != null); Debug.Assert(triangulator != null); FillMeshDataContainers(ref m_VerticesTemp, ref m_EdgesTemp, out var weightData, out var hasWeightData); var indices = new List <int>(); triangulator.Triangulate(m_VerticesTemp, m_EdgesTemp, indices); if (m_VerticesTemp.Count == 0) { spriteMeshData.Clear(); CreateQuad(); FillMeshDataContainers(ref m_VerticesTemp, ref m_EdgesTemp, out weightData, out hasWeightData); indices.Clear(); triangulator.Triangulate(m_VerticesTemp, m_EdgesTemp, indices); } spriteMeshData.Clear(); spriteMeshData.edges.AddRange(m_EdgesTemp); spriteMeshData.indices.AddRange(indices); var hasNewVertices = m_VerticesTemp.Count != weightData.Count; for (var i = 0; i < m_VerticesTemp.Count; ++i) { var boneWeight = default(BoneWeight); if (!hasNewVertices) { boneWeight = weightData[i].ToBoneWeight(true); } spriteMeshData.AddVertex(m_VerticesTemp[i], boneWeight); } if (hasNewVertices && hasWeightData) { CalculateWeights(new BoundedBiharmonicWeightsGenerator(), null, 0.01f); } }
public static void Triangulate(this SpriteMeshData spriteMeshData, ITriangulator triangulator) { Debug.Assert(triangulator != null); m_VerticesTemp.Clear(); for (int i = 0; i < spriteMeshData.vertices.Count; ++i) { m_VerticesTemp.Add(spriteMeshData.vertices[i].position); } triangulator.Triangulate(m_VerticesTemp, spriteMeshData.edges, spriteMeshData.indices); }
public void Triangulate(ITriangulator triangulator) { Debug.Assert(spriteMeshData != null); Debug.Assert(triangulator != null); m_VerticesTemp.Clear(); for (int i = 0; i < spriteMeshData.vertexCount; ++i) { m_VerticesTemp.Add(spriteMeshData.GetPosition(i)); } triangulator.Triangulate(m_VerticesTemp, spriteMeshData.edges, spriteMeshData.indices); }
/// <inheritdoc /> public IMesh Triangulate(IList <Vertex> points) { return(triangulator.Triangulate(points, config)); }