diff --git a/OpenSim/Region/Physics/OdePlugin/Meshing/Extruder.cs b/OpenSim/Region/Physics/OdePlugin/Meshing/Extruder.cs deleted file mode 100755 index 497e039a58..0000000000 --- a/OpenSim/Region/Physics/OdePlugin/Meshing/Extruder.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenSim.Region.Physics.OdePlugin.Meshing -{ - class Extruder - { - public float startParameter; - public float stopParameter; - public Manager.PhysicsVector size; - - public Mesh Extrude(Mesh m) - { - // Currently only works for iSteps=1; - Mesh result = new Mesh(); - - Mesh workingPlus = m.Clone(); - Mesh workingMinus = m.Clone(); - - foreach (Vertex v in workingPlus.vertices) - { - if (v == null) - continue; - - v.Z = +.5f; - v.X *= size.X; - v.Y *= size.Y; - v.Z *= size.Z; - } - - foreach (Vertex v in workingMinus.vertices) - { - if (v == null) - continue; - - v.Z = -.5f; - v.X *= size.X; - v.Y *= size.Y; - v.Z *= size.Z; - } - - foreach (Triangle t in workingMinus.triangles) - { - t.invertNormal(); - } - - result.Append(workingMinus); - result.Append(workingPlus); - - int iLastNull = 0; - for (int i = 0; i < workingPlus.vertices.Count; i++) - { - int iNext = (i + 1); - - if (workingPlus.vertices[i] == null) // Can't make a simplex here - { - iLastNull = i+1; - continue; - } - - if (i == workingPlus.vertices.Count-1) // End of list - { - iNext = iLastNull; - } - - if (workingPlus.vertices[iNext] == null) // Null means wrap to begin of last segment - { - iNext = iLastNull; - } - - Triangle tSide; - tSide = new Triangle(workingPlus.vertices[i], workingMinus.vertices[i], workingPlus.vertices[iNext]); - result.Add(tSide); - - tSide = new Triangle(workingPlus.vertices[iNext], workingMinus.vertices[i], workingMinus.vertices[iNext]); - result.Add(tSide); - } - - return result; - } - } -} diff --git a/OpenSim/Region/Physics/OdePlugin/Meshing/HelperTypes.cs b/OpenSim/Region/Physics/OdePlugin/Meshing/HelperTypes.cs deleted file mode 100644 index 3b20af77bc..0000000000 --- a/OpenSim/Region/Physics/OdePlugin/Meshing/HelperTypes.cs +++ /dev/null @@ -1,306 +0,0 @@ -/* -* Copyright (c) Contributors, http://opensimulator.org/ -* See CONTRIBUTORS.TXT for a full list of copyright holders. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the OpenSim Project nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY -* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using OpenSim.Framework.Console; -using OpenSim.Region.Physics.Manager; - -using OpenSim.Region.Physics.OdePlugin.Meshing; - -public class Vertex : PhysicsVector, IComparable -{ - public Vertex(float x, float y, float z) - : base(x, y, z) - { - } - - public Vertex(PhysicsVector v) - : base(v.X, v.Y, v.Z) - { - } - - public Vertex Clone() - { - return new Vertex(X, Y, Z); - } - - public static Vertex FromAngle(double angle) - { - return new Vertex((float)Math.Cos(angle), (float)Math.Sin(angle), 0.0f); - } - - - public virtual bool Equals(Vertex v, float tolerance) - { - PhysicsVector diff = this - v; - float d = diff.length(); - if (d < tolerance) - return true; - - return false; - } - - - public int CompareTo(Vertex other) - { - if (X < other.X) - return -1; - - if (X > other.X) - return 1; - - if (Y < other.Y) - return -1; - - if (Y > other.Y) - return 1; - - if (Z < other.Z) - return -1; - - if (Z > other.Z) - return 1; - - return 0; - } - - public static bool operator >(Vertex me, Vertex other) - { - return me.CompareTo(other) > 0; - } - - public static bool operator <(Vertex me, Vertex other) - { - return me.CompareTo(other) < 0; - } - public String ToRaw() - { - // Why this stuff with the number formatter? - // Well, the raw format uses the english/US notation of numbers - // where the "," separates groups of 1000 while the "." marks the border between 1 and 10E-1. - // The german notation uses these characters exactly vice versa! - // The Float.ToString() routine is a localized one, giving different results depending on the country - // settings your machine works with. Unusable for a machine readable file format :-( - NumberFormatInfo nfi = new NumberFormatInfo(); - nfi.NumberDecimalSeparator = "."; - nfi.NumberDecimalDigits = 3; - - String s1 = X.ToString("N2", nfi) + " " + Y.ToString("N2", nfi) + " " + Z.ToString("N2", nfi); - - return s1; - } - -} - -public class Triangle -{ - public Vertex v1; - public Vertex v2; - public Vertex v3; - - private float radius_square; - private float cx; - private float cy; - - public Triangle(Vertex _v1, Vertex _v2, Vertex _v3) - { - v1 = _v1; - v2 = _v2; - v3 = _v3; - - CalcCircle(); - } - - public bool isInCircle(float x, float y) - { - float dx, dy; - float dd; - - dx = x - cx; - dy = y - cy; - - dd = dx*dx + dy*dy; - if (dd < radius_square) - return true; - else - return false; - } - - public bool isDegraded() - { - // This means, the vertices of this triangle are somewhat strange. - // They either line up or at least two of them are identical - return (radius_square == 0.0); - } - - private void CalcCircle() - { - // Calculate the center and the radius of a circle given by three points p1, p2, p3 - // It is assumed, that the triangles vertices are already set correctly - double p1x, p2x, p1y, p2y, p3x, p3y; - - // Deviation of this routine: - // A circle has the general equation (M-p)^2=r^2, where M and p are vectors - // this gives us three equations f(p)=r^2, each for one point p1, p2, p3 - // putting respectively two equations together gives two equations - // f(p1)=f(p2) and f(p1)=f(p3) - // bringing all constant terms to one side brings them to the form - // M*v1=c1 resp.M*v2=c2 where v1=(p1-p2) and v2=(p1-p3) (still vectors) - // and c1, c2 are scalars (Naming conventions like the variables below) - // Now using the equations that are formed by the components of the vectors - // and isolate Mx lets you make one equation that only holds My - // The rest is straight forward and eaasy :-) - // - - /* helping variables for temporary results */ - double c1, c2; - double v1x, v1y, v2x, v2y; - - double z, n; - - double rx, ry; - - // Readout the three points, the triangle consists of - p1x = v1.X; - p1y = v1.Y; - - p2x = v2.X; - p2y = v2.Y; - - p3x = v3.X; - p3y = v3.Y; - - /* calc helping values first */ - c1 = (p1x*p1x + p1y*p1y - p2x*p2x - p2y*p2y)/2; - c2 = (p1x*p1x + p1y*p1y - p3x*p3x - p3y*p3y)/2; - - v1x = p1x - p2x; - v1y = p1y - p2y; - - v2x = p1x - p3x; - v2y = p1y - p3y; - - z = (c1*v2x - c2*v1x); - n = (v1y*v2x - v2y*v1x); - - if (n == 0.0) // This is no triangle, i.e there are (at least) two points at the same location - { - radius_square = 0.0f; - return; - } - - cy = (float) (z/n); - - if (v2x != 0.0) - { - cx = (float) ((c2 - v2y*cy)/v2x); - } - else if (v1x != 0.0) - { - cx = (float) ((c1 - v1y*cy)/v1x); - } - else - { - Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */ - } - - rx = (p1x - cx); - ry = (p1y - cy); - - radius_square = (float) (rx*rx + ry*ry); - } - - public List GetSimplices() - { - List result = new List(); - Simplex s1 = new Simplex(v1, v2); - Simplex s2 = new Simplex(v2, v3); - Simplex s3 = new Simplex(v3, v1); - - result.Add(s1); - result.Add(s2); - result.Add(s3); - - return result; - } - - public override String ToString() - { - NumberFormatInfo nfi = new NumberFormatInfo(); - nfi.CurrencyDecimalDigits = 2; - nfi.CurrencyDecimalSeparator = "."; - - String s1 = "<" + v1.X.ToString(nfi) + "," + v1.Y.ToString(nfi) + "," + v1.Z.ToString(nfi) + ">"; - String s2 = "<" + v2.X.ToString(nfi) + "," + v2.Y.ToString(nfi) + "," + v2.Z.ToString(nfi) + ">"; - String s3 = "<" + v3.X.ToString(nfi) + "," + v3.Y.ToString(nfi) + "," + v3.Z.ToString(nfi) + ">"; - - return s1 + ";" + s2 + ";" + s3; - } - - public PhysicsVector getNormal() - { - // Vertices - - // Vectors for edges - PhysicsVector e1; - PhysicsVector e2; - - e1 = new PhysicsVector(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z); - e2 = new PhysicsVector(v1.X - v3.X, v1.Y - v3.Y, v1.Z - v3.Z); - - // Cross product for normal - PhysicsVector n = PhysicsVector.cross(e1, e2); - - // Length - float l = n.length(); - - // Normalized "normal" - n = n / l; - - return n; - } - - public void invertNormal() - { - Vertex vt; - vt = v1; - v1 = v2; - v2 = vt; - } - - // Dumps a triangle in the "raw faces" format, blender can import. This is for visualisation and - // debugging purposes - public String ToStringRaw() - { - String output = v1.ToRaw() + " " + v2.ToRaw() + " " +v3.ToRaw(); - return output; - } -} diff --git a/OpenSim/Region/Physics/OdePlugin/Meshing/Mesh.cs b/OpenSim/Region/Physics/OdePlugin/Meshing/Mesh.cs deleted file mode 100755 index 5a51703518..0000000000 --- a/OpenSim/Region/Physics/OdePlugin/Meshing/Mesh.cs +++ /dev/null @@ -1,197 +0,0 @@ -using System; -using System.IO; -using System.Collections.Generic; -using System.Text; - -using System.Runtime.InteropServices; - - -using OpenSim.Region.Physics.Manager; - -namespace OpenSim.Region.Physics.OdePlugin.Meshing -{ - public class Mesh - { - public List vertices; - public List triangles; - - public float[] normals; - - public Mesh() - { - vertices = new List(); - triangles = new List(); - } - - public Mesh Clone() - { - Mesh result = new Mesh(); - - foreach (Vertex v in vertices) - { - if (v == null) - result.vertices.Add(null); - else - result.vertices.Add(v.Clone()); - } - - foreach (Triangle t in triangles) - { - int iV1, iV2, iV3; - iV1 = this.vertices.IndexOf(t.v1); - iV2 = this.vertices.IndexOf(t.v2); - iV3 = this.vertices.IndexOf(t.v3); - - Triangle newT = new Triangle(result.vertices[iV1], result.vertices[iV2], result.vertices[iV3]); - result.Add(newT); - } - - return result; - } - - - - public void Add(Triangle triangle) - { - int i; - i = vertices.IndexOf(triangle.v1); - if (i < 0) - throw new ArgumentException("Vertex v1 not known to mesh"); - i = vertices.IndexOf(triangle.v2); - if (i < 0) - throw new ArgumentException("Vertex v2 not known to mesh"); - i = vertices.IndexOf(triangle.v3); - if (i < 0) - throw new ArgumentException("Vertex v3 not known to mesh"); - - triangles.Add(triangle); - } - - public void Add(Vertex v) - { - vertices.Add(v); - } - - public void Remove(Vertex v) - { - int i; - - // First, remove all triangles that are build on v - for (i = 0; i < triangles.Count; i++) - { - Triangle t = triangles[i]; - if (t.v1 == v || t.v2 == v || t.v3 == v) - { - triangles.RemoveAt(i); - i--; - } - } - - // Second remove v itself - vertices.Remove(v); - } - - public void RemoveTrianglesOutside(SimpleHull hull) - { - int i; - - for (i = 0; i < triangles.Count; i++) - { - Triangle t = triangles[i]; - Vertex v1 = t.v1; - Vertex v2 = t.v2; - Vertex v3 = t.v3; - PhysicsVector m = v1 + v2 + v3; - m /= 3.0f; - if (!hull.IsPointIn(new Vertex(m))) - { - triangles.RemoveAt(i); - i--; - } - } - } - - - public void Add(List lv) - { - foreach (Vertex v in lv) - { - vertices.Add(v); - } - } - - public float[] getVertexListAsFloat() - { - float[] result = new float[vertices.Count * 3]; - for (int i = 0; i < vertices.Count; i++) - { - Vertex v = vertices[i]; - if (v == null) - continue; - result[3 * i + 0] = v.X; - result[3 * i + 1] = v.Y; - result[3 * i + 2] = v.Z; - } - GCHandle.Alloc(result, GCHandleType.Pinned); - return result; - } - - public int[] getIndexListAsInt() - { - int[] result = new int[triangles.Count * 3]; - for (int i = 0; i < triangles.Count; i++) - { - Triangle t = triangles[i]; - result[3 * i + 0] = vertices.IndexOf(t.v1); - result[3 * i + 1] = vertices.IndexOf(t.v2); - result[3 * i + 2] = vertices.IndexOf(t.v3); - } - GCHandle.Alloc(result, GCHandleType.Pinned); - return result; - } - - - public void Append(Mesh newMesh) - { - foreach (Vertex v in newMesh.vertices) - vertices.Add(v); - - foreach (Triangle t in newMesh.triangles) - Add(t); - - } - - // Do a linear transformation of mesh. - public void TransformLinear(float[,] matrix, float[] offset) - { - foreach (Vertex v in vertices) - { - if (v == null) - continue; - float x, y, z; - x = v.X * matrix[0, 0] + v.Y * matrix[1, 0] + v.Z * matrix[2, 0]; - y = v.X * matrix[0, 1] + v.Y * matrix[1, 1] + v.Z * matrix[2, 1]; - z = v.X * matrix[0, 2] + v.Y * matrix[1, 2] + v.Z * matrix[2, 2]; - v.X = x + offset[0]; - v.Y = y + offset[1]; - v.Z = z + offset[2]; - } - } - - public void DumpRaw(String path, String name, String title) - { - if (path == null) - return; - String fileName = name + "_" + title + ".raw"; - String completePath = Path.Combine(path, fileName); - StreamWriter sw = new StreamWriter(completePath); - foreach (Triangle t in triangles) - { - String s = t.ToStringRaw(); - sw.WriteLine(s); - } - sw.Close(); - } - } - -} diff --git a/OpenSim/Region/Physics/OdePlugin/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/OdePlugin/Meshing/Meshmerizer.cs deleted file mode 100644 index 37fbb8a496..0000000000 --- a/OpenSim/Region/Physics/OdePlugin/Meshing/Meshmerizer.cs +++ /dev/null @@ -1,375 +0,0 @@ -/* -* Copyright (c) Contributors, http://opensimulator.org/ -* See CONTRIBUTORS.TXT for a full list of copyright holders. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the OpenSim Project nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY -* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -*/ - -using System; -using System.IO; -using System.Globalization; -using System.Diagnostics; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using OpenSim.Framework; -using OpenSim.Framework.Console; -using OpenSim.Region.Physics.Manager; - -namespace OpenSim.Region.Physics.OdePlugin.Meshing -{ - - public class Meshmerizer - { - // Setting baseDir to a path will enable the dumping of raw files - // raw files can be imported by blender so a visual inspection of the results can be done - // const string baseDir = "rawFiles"; - const string baseDir = null; - - static void IntersectionParameterPD(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu) - { - // p1, p2, points on the straight - // r1, r2, directional vectors of the straight. Not necessarily of length 1! - // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points, - // thus allowing to decide whether an intersection is between two points - - float r1x = r1.X; - float r1y = r1.Y; - float r2x = r2.X; - float r2y = r2.Y; - - float denom = r1y*r2x - r1x*r2y; - - if (denom == 0.0) - { - lambda = Single.NaN; - mu = Single.NaN; - return; - } - - float p1x = p1.X; - float p1y = p1.Y; - float p2x = p2.X; - float p2y = p2.Y; - lambda = (-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x) / denom; - mu = (-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x) / denom; - - } - - private static List FindInfluencedTriangles(List triangles, Vertex v) - { - List influenced = new List(); - foreach (Triangle t in triangles) - { - if (t.isInCircle(v.X, v.Y)) - { - influenced.Add(t); - } - } - return influenced; - } - - - private static void InsertVertices(List vertices, int usedForSeed, List triangles) - { - // This is a variant of the delaunay algorithm - // each time a new vertex is inserted, all triangles that are influenced by it are deleted - // and replaced by new ones including the new vertex - // It is not very time efficient but easy to implement. - - int iCurrentVertex; - int iMaxVertex = vertices.Count; - for (iCurrentVertex = usedForSeed; iCurrentVertex < iMaxVertex; iCurrentVertex++) - { - // Background: A triangle mesh fulfills the delaunay condition if (iff!) - // each circumlocutory circle (i.e. the circle that touches all three corners) - // of each triangle is empty of other vertices. - // Obviously a single (seeding) triangle fulfills this condition. - // If we now add one vertex, we need to reconstruct all triangles, that - // do not fulfill this condition with respect to the new triangle - - // Find the triangles that are influenced by the new vertex - Vertex v=vertices[iCurrentVertex]; - if (v == null) - continue; // Null is polygon stop marker. Ignore it - List influencedTriangles=FindInfluencedTriangles(triangles, v); - - List simplices = new List(); - - // Reconstruction phase. First step, dissolve each triangle into it's simplices, - // i.e. it's "border lines" - // Goal is to find "inner" borders and delete them, while the hull gets conserved. - // Inner borders are special in the way that they always come twice, which is how we detect them - foreach (Triangle t in influencedTriangles) - { - List newSimplices = t.GetSimplices(); - simplices.AddRange(newSimplices); - triangles.Remove(t); - } - // Now sort the simplices. That will make identical ones reside side by side in the list - simplices.Sort(); - - // Look for duplicate simplices here. - // Remember, they are directly side by side in the list right now, - // So we only check directly neighbours - int iSimplex; - List innerSimplices = new List(); - for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards - { - if (simplices[iSimplex - 1].CompareTo(simplices[iSimplex]) == 0) - { - innerSimplices.Add(simplices[iSimplex - 1]); - innerSimplices.Add(simplices[iSimplex]); - } - } - - foreach (Simplex s in innerSimplices) - { - simplices.Remove(s); - } - - // each simplex still in the list belongs to the hull of the region in question - // The new vertex (yes, we still deal with verices here :-) ) forms a triangle - // with each of these simplices. Build the new triangles and add them to the list - foreach (Simplex s in simplices) - { - Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]); - if (!t.isDegraded()) - { - triangles.Add(t); - } - } - } - - } - - - static Mesh CreateBoxMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size) - // Builds the z (+ and -) surfaces of a box shaped prim - { - UInt16 hollowFactor = primShape.ProfileHollow; - UInt16 profileBegin = primShape.ProfileBegin; - UInt16 profileEnd = primShape.ProfileEnd; - - // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface - // of a block are basically the same - // They may be warped differently but the shape is identical - // So we only create one surface as a model and derive both plus and minus surface of the block from it - // This is done in a model space where the block spans from -.5 to +.5 in X and Y - // The mapping to Scene space is done later during the "extrusion" phase - - // Base - Vertex MM = new Vertex(-0.5f, -0.5f, 0.0f); - Vertex PM = new Vertex(+0.5f, -0.5f, 0.0f); - Vertex MP = new Vertex(-0.5f, +0.5f, 0.0f); - Vertex PP = new Vertex(+0.5f, +0.5f, 0.0f); - - Meshing.SimpleHull outerHull = new SimpleHull(); - outerHull.AddVertex(MM); - outerHull.AddVertex(PM); - outerHull.AddVertex(PP); - outerHull.AddVertex(MP); - - // Deal with cuts now - if ((profileBegin != 0) || (profileEnd != 0)) - { - double fProfileBeginAngle = profileBegin / 50000.0 * 360.0; // In degree, for easier debugging and understanding - fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y - double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0 - fProfileEndAngle -= (90.0 + 45.0); - if (fProfileBeginAngle < fProfileEndAngle) - fProfileEndAngle -= 360.0; - - // Note, that we don't want to cut out a triangle, even if this is a - // good approximation for small cuts. Indeed we want to cut out an arc - // and we approximate this arc by a polygon chain - // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space - // So it can easily be subtracted from the outer hull - int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5); // how many steps do we need with approximately 45 degree - double dStepWidth=(fProfileBeginAngle-fProfileEndAngle)/iSteps; - - Vertex origin = new Vertex(0.0f, 0.0f, 0.0f); - - // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull - SimpleHull cutHull = new SimpleHull(); - cutHull.AddVertex(origin); - for (int i=0; i 0) - { - float hollowFactorF = (float) hollowFactor/(float) 50000; - Vertex IMM = new Vertex(-0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f); - Vertex IPM = new Vertex(+0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f); - Vertex IMP = new Vertex(-0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f); - Vertex IPP = new Vertex(+0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f); - - SimpleHull holeHull = new SimpleHull(); - - holeHull.AddVertex(IMM); - holeHull.AddVertex(IMP); - holeHull.AddVertex(IPP); - holeHull.AddVertex(IPM); - - SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull); - - outerHull = hollowedHull; - - } - - Mesh m = new Mesh(); - - Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f); - Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f); - Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f); - - m.Add(Seed1); - m.Add(Seed2); - m.Add(Seed3); - - m.Add(new Triangle(Seed1, Seed2, Seed3)); - m.Add(outerHull.getVertices()); - - InsertVertices(m.vertices, 3, m.triangles); - m.DumpRaw(baseDir, primName, "Proto first Mesh"); - - m.Remove(Seed1); - m.Remove(Seed2); - m.Remove(Seed3); - m.DumpRaw(baseDir, primName, "Proto seeds removed"); - - m.RemoveTrianglesOutside(outerHull); - m.DumpRaw(baseDir, primName, "Proto outsides removed"); - - foreach (Triangle t in m.triangles) - { - PhysicsVector n = t.getNormal(); - if (n.Z < 0.0) - t.invertNormal(); - } - - Extruder extr = new Extruder(); - - extr.size = size; - - Mesh result = extr.Extrude(m); - result.DumpRaw(baseDir, primName, "Z extruded"); - return result; - } - - public static void CalcNormals(Mesh mesh) - { - int iTriangles = mesh.triangles.Count; - - mesh.normals = new float[iTriangles*3]; - - int i = 0; - foreach (Triangle t in mesh.triangles) - { - float ux, uy, uz; - float vx, vy, vz; - float wx, wy, wz; - - ux = t.v1.X; - uy = t.v1.Y; - uz = t.v1.Z; - - vx = t.v2.X; - vy = t.v2.Y; - vz = t.v2.Z; - - wx = t.v3.X; - wy = t.v3.Y; - wz = t.v3.Z; - - - // Vectors for edges - float e1x, e1y, e1z; - float e2x, e2y, e2z; - - e1x = ux - vx; - e1y = uy - vy; - e1z = uz - vz; - - e2x = ux - wx; - e2y = uy - wy; - e2z = uz - wz; - - - // Cross product for normal - float nx, ny, nz; - nx = e1y*e2z - e1z*e2y; - ny = e1z*e2x - e1x*e2z; - nz = e1x*e2y - e1y*e2x; - - // Length - float l = (float) Math.Sqrt(nx*nx + ny*ny + nz*nz); - - // Normalized "normal" - nx /= l; - ny /= l; - nz /= l; - - mesh.normals[i] = nx; - mesh.normals[i + 1] = ny; - mesh.normals[i + 2] = nz; - - i += 3; - } - } - - public static Mesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size) - { - Mesh mesh = null; - - switch (primShape.ProfileShape) - { - case ProfileShape.Square: - mesh=CreateBoxMesh(primName, primShape, size); - CalcNormals(mesh); - break; - default: - mesh = CreateBoxMesh(primName, primShape, size); - CalcNormals(mesh); - //Set default mesh to cube otherwise it'll return - // null and crash on the 'setMesh' method in the physics plugins. - //mesh = null; - break; - } - - return mesh; - } - } -} diff --git a/OpenSim/Region/Physics/OdePlugin/Meshing/SimpleHull.cs b/OpenSim/Region/Physics/OdePlugin/Meshing/SimpleHull.cs deleted file mode 100755 index 2caa818c00..0000000000 --- a/OpenSim/Region/Physics/OdePlugin/Meshing/SimpleHull.cs +++ /dev/null @@ -1,363 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -using OpenSim.Framework.Console; - -namespace OpenSim.Region.Physics.OdePlugin.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 - { - public Vertex v1; - public Vertex v2; - - public Simplex(Vertex _v1, Vertex _v2) - { - v1 = _v1; - v2 = _v2; - } - - public int CompareTo(Simplex other) - { - - Vertex lv1, lv2, ov1, ov2, temp; - - lv1 = v1; - lv2 = v2; - ov1 = other.v1; - ov2 = other.v2; - - if (lv1 > lv2) - { - temp = lv1; - lv1 = lv2; - lv2 = temp; - } - - if (ov1 > ov2) - { - temp = ov1; - ov1 = ov2; - ov2 = temp; - } - - if (lv1 > ov1) - { - return 1; - } - if (lv1 < ov1) - { - return -1; - } - - if (lv2 > ov2) - { - return 1; - } - if (lv2 < ov2) - { - return -1; - } - - return 0; - } - - private static void intersectParameter(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu) - { - // Intersects two straights - // p1, p2, points on the straight - // r1, r2, directional vectors of the straight. Not necessarily of length 1! - // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points, - // thus allowing to decide whether an intersection is between two points - - float r1x = r1.X; - float r1y = r1.Y; - float r2x = r2.X; - float r2y = r2.Y; - - float denom = r1y*r2x - r1x*r2y; - - float p1x = p1.X; - float p1y = p1.Y; - float p2x = p2.X; - float p2y = p2.Y; - - float z1=-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x; - float z2=-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x; - - if (denom == 0.0f) // Means the straights are parallel. Either no intersection or an infinite number of them - { - if (z1==0.0f) {// Means they are identical -> many, many intersections - lambda = Single.NaN; - mu = Single.NaN; - } else { - lambda = Single.PositiveInfinity; - mu = Single.PositiveInfinity; - } - return; - - } - - - - lambda = z1 / denom; - mu = z2 / denom; - - } - - - // Intersects the simplex with another one. - // the borders are used to deal with float inaccuracies - // As a rule of thumb, the borders are - // lowerBorder1 : 0.0 - // lowerBorder2 : 0.0 - // upperBorder1 : 1.0 - // upperBorder2 : 1.0 - // Set these to values near the given parameters (e.g. 0.001 instead of 1 to exclude simplex starts safely, or to -0.001 to include them safely) - public static PhysicsVector Intersect( - Simplex s1, - Simplex s2, - float lowerBorder1, - float lowerBorder2, - float upperBorder1, - float upperBorder2) - { - PhysicsVector firstSimplexDirection = s1.v2 - s1.v1; - PhysicsVector secondSimplexDirection = s2.v2 - s2.v1; - - float lambda = 0.0f; - float mu = 0.0f; - - // Give us the parameters of an intersection. This subroutine does *not* take the constraints - // (intersection must be between v1 and v2 and it must be in the positive direction of the ray) - // into account. We do that afterwards. - intersectParameter(s1.v1, firstSimplexDirection, s2.v1, secondSimplexDirection, ref lambda, ref mu); - - if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel. - return null; - - if (Single.IsNaN(lambda)) // Special case. many, many intersections. - return null; - - if (lambda > upperBorder1) // We're behind v2 - return null; - - if (lambda < lowerBorder1) - return null; - - if (mu < lowerBorder2) // outside simplex 2 - return null; - - if (mu > upperBorder2) // outside simplex 2 - return null; - - return s1.v1 + lambda * firstSimplexDirection; - - } - - // Intersects the simplex with a ray. The ray is defined as all p=origin + lambda*direction - // where lambda >= 0 - public PhysicsVector RayIntersect(Vertex origin, PhysicsVector direction, bool bEndsIncluded) - { - PhysicsVector simplexDirection = v2 - v1; - - float lambda = 0.0f; - float mu = 0.0f; - - // Give us the parameters of an intersection. This subroutine does *not* take the constraints - // (intersection must be between v1 and v2 and it must be in the positive direction of the ray) - // into account. We do that afterwards. - intersectParameter(v1, simplexDirection, origin, direction, ref lambda, ref mu); - - if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel. - return null; - - if (Single.IsNaN(lambda)) // Special case. many, many intersections. - return null; - - if (mu < 0.0) // We're on the wrong side of the ray - return null; - - if (lambda > 1.0) // We're behind v2 - return null; - - if (lambda == 1.0 && !bEndsIncluded) - return null; // The end of the simplices are not included - - if (lambda < 0.0f) // we're before v1; - return null; - - return this.v1 + lambda * simplexDirection; - - } - - - } -}