using System; using System.Collections.Generic; using System.Text; using OpenSim.Framework.Console; namespace OpenSim.Region.Physics.Meshing { // A simple hull is a set of vertices building up to simplices that border a region // The word simple referes to the fact, that this class assumes, that all simplices // do not intersect // Simple hulls can be added and subtracted. // Vertices can be checked to lie inside a hull // Also note, that the sequence of the vertices is important and defines if the region that // is defined by the hull lies inside or outside the simplex chain public class SimpleHull { List vertices = new List(); List holeVertices = new List(); // Only used, when the hull is hollow // Adds a vertex to the end of the list public void AddVertex(Vertex v) { vertices.Add(v); } override public String ToString() { String result=""; foreach (Vertex v in vertices) { result += "b:" + v.ToString() + "\n"; } return result; } public List getVertices() { List newVertices = new List(); newVertices.AddRange(vertices); newVertices.Add(null); newVertices.AddRange(holeVertices); return newVertices; } public SimpleHull Clone() { SimpleHull result = new SimpleHull(); foreach (Vertex v in vertices) { result.AddVertex(v.Clone()); } foreach (Vertex v in this.holeVertices) { result.holeVertices.Add(v.Clone()); } return result; } public bool IsPointIn(Vertex v1) { int iCounter=0; List simplices=buildSimplexList(); foreach (Simplex s in simplices) { // Send a ray along the positive X-Direction // Note, that this direction must correlate with the "below" interpretation // of handling for the special cases below Manager.PhysicsVector intersection = s.RayIntersect(v1, new Manager.PhysicsVector(1.0f, 0.0f, 0.0f), true); if (intersection == null) continue; // No intersection. Done. More tests to follow otherwise // Did we hit the end of a simplex? // Then this can be one of two special cases: // 1. we go through a border exactly at a joint // 2. we have just marginally touched a corner // 3. we can slide along a border // Solution: If the other vertex is "below" the ray, we don't count it // Thus corners pointing down are counted twice, corners pointing up are not counted // borders are counted once if (intersection.IsIdentical(s.v1, 0.001f)) { if (s.v2.Y < v1.Y) continue; } // Do this for the other vertex two if (intersection.IsIdentical(s.v2, 0.001f)) { if (s.v1.Y buildSimplexList() { List result = new List(); // Not asserted but assumed: at least three vertices for (int i=0; i simple = buildSimplexList(); foreach (Simplex sTest in simple) { Manager.PhysicsVector vvTemp = Simplex.Intersect(sTest, s, -.001f, -.001f, 0.999f, .999f); Vertex vTemp=null; if (vvTemp != null) vTemp = new Vertex(vvTemp); if (vTemp!=null) { Manager.PhysicsVector diff=(s.v1-vTemp); float distTemp=diff.length(); if (bestIntersection==null || distTemp