From d20d621ab1aaa972e5d3157b30c67251c26d3912 Mon Sep 17 00:00:00 2001 From: Dalien Talbot Date: Sun, 30 Sep 2007 08:50:49 +0000 Subject: Corrected the typo in the folder name. --- .../Physics/OdePlugin/Meshing/HelperTypes.cs | 279 ++++++++++ .../Physics/OdePlugin/Meshing/Meshmerizer.cs | 560 +++++++++++++++++++++ .../Physics/OdePlugin/Meshing\\/HelperTypes.cs" | 279 ---------- .../Physics/OdePlugin/Meshing\\/Meshmerizer.cs" | 560 --------------------- 4 files changed, 839 insertions(+), 839 deletions(-) create mode 100644 OpenSim/Region/Physics/OdePlugin/Meshing/HelperTypes.cs create mode 100644 OpenSim/Region/Physics/OdePlugin/Meshing/Meshmerizer.cs delete mode 100644 "OpenSim/Region/Physics/OdePlugin/Meshing\\/HelperTypes.cs" delete mode 100644 "OpenSim/Region/Physics/OdePlugin/Meshing\\/Meshmerizer.cs" (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/OdePlugin/Meshing/HelperTypes.cs b/OpenSim/Region/Physics/OdePlugin/Meshing/HelperTypes.cs new file mode 100644 index 0000000..3d40c04 --- /dev/null +++ b/OpenSim/Region/Physics/OdePlugin/Meshing/HelperTypes.cs @@ -0,0 +1,279 @@ +using System; +using System.Globalization; +using System.Diagnostics; +using System.Collections.Generic; + +using OpenSim.Region.Physics.Manager; + +public class Vertex : IComparable +{ + public String name; + public PhysicsVector point; + + public Vertex(String name, float x, float y, float z) + { + this.name = name; + point = new PhysicsVector(x, y, z); + } + + public int CompareTo(Vertex other) + { + if (point.X < other.point.X) + return -1; + + if (point.X > other.point.X) + return 1; + + if (point.Y < other.point.Y) + return -1; + + if (point.Y > other.point.Y) + return 1; + + if (point.Z < other.point.Z) + return -1; + + if (point.Z > other.point.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 class Simplex : IComparable +{ + public Vertex v1; + public Vertex v2; + + public Simplex(Vertex _v1, Vertex _v2) + { + // Presort indices to make sorting (comparing) easier + if (_v1 > _v2) + { + v1 = _v1; + v2 = _v2; + } + else + { + v1 = _v2; + v2 = _v1; + } + } + + public int CompareTo(Simplex other) + { + if (v1 > other.v1) + { + return 1; + } + if (v1 < other.v1) + { + return -1; + } + + if (v2 > other.v2) + { + return 1; + } + if (v2 < other.v2) + { + return -1; + } + + return 0; + } + +}; + +public class Triangle +{ + public Vertex v1; + public Vertex v2; + public Vertex v3; + + float radius_square; + float cx; + 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 - this.cx; + dy = y - this.cy; + + dd = dx * dx + dy * dy; + if (dd < this.radius_square) + return true; + else + return false; + } + + + 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.point.X; + p1y = v1.point.Y; + + p2x = v2.point.X; + p2y = v2.point.Y; + + p3x = v3.point.X; + p3y = v3.point.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; + } + + this.cy = (float)(z / n); + + if (v2x != 0.0) + { + this.cx = (float)((c2 - v2y * this.cy) / v2x); + } + else if (v1x != 0.0) + { + this.cx = (float)((c1 - v1y * this.cy) / v1x); + } + else + { + Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */ + } + + rx = (p1x - this.cx); + ry = (p1y - this.cy); + + this.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.point.X.ToString(nfi) + "," + v1.point.Y.ToString(nfi) + "," + v1.point.Z.ToString(nfi) + ">"; + String s2 = "<" + v2.point.X.ToString(nfi) + "," + v2.point.Y.ToString(nfi) + "," + v2.point.Z.ToString(nfi) + ">"; + String s3 = "<" + v3.point.X.ToString(nfi) + "," + v3.point.Y.ToString(nfi) + "," + v3.point.Z.ToString(nfi) + ">"; + + return s1 + ";" + s2 + ";" + s3; + + } + + public PhysicsVector getNormal() + { + // Vertices + + // Vectors for edges + PhysicsVector e1; + PhysicsVector e2; + + e1 = new PhysicsVector(v1.point.X - v2.point.X, v1.point.Y - v2.point.Y, v1.point.Z - v2.point.Z); + e2 = new PhysicsVector(v1.point.X - v3.point.X, v1.point.Y - v3.point.Y, v1.point.Z - v3.point.Z); + + // Cross product for normal + PhysicsVector n = new PhysicsVector(); + float nx, ny, nz; + n.X = e1.Y * e2.Z - e1.Z * e2.Y; + n.Y = e1.Z * e2.X - e1.X * e2.Z; + n.Z = e1.X * e2.Y - e1.Y * e2.X; + + // Length + float l = (float)Math.Sqrt(n.X * n.X + n.Y * n.Y + n.Z * n.Z); + + // Normalized "normal" + n.X /= l; + n.Y /= l; + n.Z /= l; + + return n; + } + + public void invertNormal() + { + Vertex vt; + vt = v1; + v1 = v2; + v2 = vt; + } +} + diff --git a/OpenSim/Region/Physics/OdePlugin/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/OdePlugin/Meshing/Meshmerizer.cs new file mode 100644 index 0000000..28dca41 --- /dev/null +++ b/OpenSim/Region/Physics/OdePlugin/Meshing/Meshmerizer.cs @@ -0,0 +1,560 @@ +using System; +using System.Globalization; +using System.Diagnostics; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; + +using OpenSim.Framework.Types; +using OpenSim.Region.Physics.Manager; + +namespace OpenSim.Region.Physics.OdePlugin +{ + public class Mesh + { + public List vertices; + public List triangles; + + public float[] normals; + + public Mesh() + { + vertices = new List(); + triangles = new List(); + } + + 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 float[] getVertexListAsFloat() + { + float[] result = new float[vertices.Count * 3]; + for (int i = 0; i < vertices.Count; i++) + { + Vertex v = vertices[i]; + PhysicsVector point = v.point; + result[3 * i + 0] = point.X; + result[3 * i + 1] = point.Y; + result[3 * i + 2] = point.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); + + } + } + + + + public class Meshmerizer + { + + static List FindInfluencedTriangles(List triangles, Vertex v) + { + List influenced = new List(); + foreach (Triangle t in triangles) + { + float dx, dy; + + if (t.isInCircle(v.point.X, v.point.Y)) + { + influenced.Add(t); + } + } + return influenced; + } + + + static void InsertVertices(List vertices, int usedForSeed, List triangles, List innerBorders) + { + // 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]; + 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 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 + 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]); + triangles.Add(t); + } + } + + // At this point all vertices should be inserted into the mesh + // But the areas, that should be kept free still are filled with triangles + // We have to remove them. For this we have a list of indices to vertices. + // Each triangle that solemnly constists of vertices from the inner border + // are deleted + + List innerTriangles = new List(); + foreach (Triangle t in triangles) + { + if ( + innerBorders.Contains(vertices.IndexOf(t.v1)) + && innerBorders.Contains(vertices.IndexOf(t.v2)) + && innerBorders.Contains(vertices.IndexOf(t.v3)) + ) + innerTriangles.Add(t); + } + foreach (Triangle t in innerTriangles) + { + triangles.Remove(t); + } + } + + + static Mesh CreateBoxMeshX(PrimitiveBaseShape primShape, PhysicsVector size) + // Builds the x (+ and -) surfaces of a box shaped prim + { + UInt16 hollowFactor = primShape.ProfileHollow; + Mesh meshMX = new Mesh(); + + + // Surface 0, -X + meshMX.Add(new Vertex("-X-Y-Z", -size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); + meshMX.Add(new Vertex("-X+Y-Z", -size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); + meshMX.Add(new Vertex("-X-Y+Z", -size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f)); + meshMX.Add(new Vertex("-X+Y+Z", -size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f)); + + meshMX.Add(new Triangle(meshMX.vertices[0], meshMX.vertices[2], meshMX.vertices[1])); + meshMX.Add(new Triangle(meshMX.vertices[1], meshMX.vertices[2], meshMX.vertices[3])); + + + Mesh meshPX = new Mesh(); + // Surface 1, +X + meshPX.Add(new Vertex("+X-Y-Z", +size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); + meshPX.Add(new Vertex("+X+Y-Z", +size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); + meshPX.Add(new Vertex("+X-Y+Z", +size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f)); + meshPX.Add(new Vertex("+X+Y+Z", +size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f)); + + + meshPX.Add(new Triangle(meshPX.vertices[0], meshPX.vertices[1], meshPX.vertices[2])); + meshPX.Add(new Triangle(meshPX.vertices[2], meshPX.vertices[1], meshPX.vertices[3])); + + + if (hollowFactor > 0) + { + float hollowFactorF = (float)hollowFactor / (float)50000; + + Vertex IPP; + Vertex IPM; + Vertex IMP; + Vertex IMM; + + IPP = new Vertex("Inner-X+Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); + IPM = new Vertex("Inner-X+Y-Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); + IMP = new Vertex("Inner-X-Y+Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); + IMM = new Vertex("Inner-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); + + meshMX.Add(IPP); + meshMX.Add(IPM); + meshMX.Add(IMP); + meshMX.Add(IMM); + + meshMX.Add(new Triangle(IPP, IMP, IPM)); + meshMX.Add(new Triangle(IPM, IMP, IMM)); + + foreach (Triangle t in meshMX.triangles) + { + PhysicsVector n = t.getNormal(); + } + + + + IPP = new Vertex("Inner+X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); + IPM = new Vertex("Inner+X+Y-Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); + IMP = new Vertex("Inner+X-Y+Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); + IMM = new Vertex("Inner+X-Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); + + meshPX.Add(IPP); + meshPX.Add(IPM); + meshPX.Add(IMP); + meshPX.Add(IMM); + + meshPX.Add(new Triangle(IPP, IPM, IMP)); + meshPX.Add(new Triangle(IMP, IPM, IMM)); + + foreach (Triangle t in meshPX.triangles) + { + PhysicsVector n = t.getNormal(); + } + } + + Mesh result = new Mesh(); + result.Append(meshMX); + result.Append(meshPX); + + return result; + } + + + + static Mesh CreateBoxMeshY(PrimitiveBaseShape primShape, PhysicsVector size) + // Builds the y (+ and -) surfaces of a box shaped prim + { + UInt16 hollowFactor = primShape.ProfileHollow; + + // (M)inus Y + Mesh MeshMY = new Mesh(); + MeshMY.Add(new Vertex("-X-Y-Z", -size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); + MeshMY.Add(new Vertex("+X-Y-Z", +size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); + MeshMY.Add(new Vertex("-X-Y+Z", -size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f)); + MeshMY.Add(new Vertex("+X-Y+Z", +size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f)); + + MeshMY.Add(new Triangle(MeshMY.vertices[0], MeshMY.vertices[1], MeshMY.vertices[2])); + MeshMY.Add(new Triangle(MeshMY.vertices[2], MeshMY.vertices[1], MeshMY.vertices[3])); + + // (P)lus Y + Mesh MeshPY = new Mesh(); + + MeshPY.Add(new Vertex("-X+Y-Z", -size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); + MeshPY.Add(new Vertex("+X+Y-Z", +size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); + MeshPY.Add(new Vertex("-X+Y+Z", -size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f)); + MeshPY.Add(new Vertex("+X+Y+Z", +size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f)); + + MeshPY.Add(new Triangle(MeshPY.vertices[1], MeshPY.vertices[0], MeshPY.vertices[2])); + MeshPY.Add(new Triangle(MeshPY.vertices[1], MeshPY.vertices[2], MeshPY.vertices[3])); + + if (hollowFactor > 0) + { + float hollowFactorF = (float)hollowFactor / (float)50000; + + Vertex IPP; + Vertex IPM; + Vertex IMP; + Vertex IMM; + + IPP = new Vertex("Inner+X-Y+Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); + IPM = new Vertex("Inner+X-Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); + IMP = new Vertex("Inner-X-Y+Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); + IMM = new Vertex("Inner-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); + + MeshMY.Add(IPP); + MeshMY.Add(IPM); + MeshMY.Add(IMP); + MeshMY.Add(IMM); + + MeshMY.Add(new Triangle(IPP, IPM, IMP)); + MeshMY.Add(new Triangle(IMP, IPM, IMM)); + + foreach (Triangle t in MeshMY.triangles) + { + PhysicsVector n = t.getNormal(); + } + + + + IPP = new Vertex("Inner+X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); + IPM=new Vertex("Inner+X+Y-Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); + IMP=new Vertex("Inner-X+Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); + IMM=new Vertex("Inner-X+Y-Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); + + MeshPY.Add(IPP); + MeshPY.Add(IPM); + MeshPY.Add(IMP); + MeshPY.Add(IMM); + + MeshPY.Add(new Triangle(IPM, IPP, IMP)); + MeshPY.Add(new Triangle(IMP, IMM, IPM)); + + foreach (Triangle t in MeshPY.triangles) + { + PhysicsVector n = t.getNormal(); + } + + + + } + + + Mesh result = new Mesh(); + result.Append(MeshMY); + result.Append(MeshPY); + + return result; + } + + static Mesh CreateBoxMeshZ(PrimitiveBaseShape primShape, PhysicsVector size) + // Builds the z (+ and -) surfaces of a box shaped prim + { + UInt16 hollowFactor = primShape.ProfileHollow; + + // Base, i.e. outer shape + // (M)inus Z + Mesh MZ = new Mesh(); + + MZ.Add(new Vertex("-X-Y-Z", -size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); + MZ.Add(new Vertex("+X-Y-Z", +size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); + MZ.Add(new Vertex("-X+Y-Z", -size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); + MZ.Add(new Vertex("+X+Y-Z", +size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); + + + MZ.Add(new Triangle(MZ.vertices[1], MZ.vertices[0], MZ.vertices[2])); + MZ.Add(new Triangle(MZ.vertices[1], MZ.vertices[2], MZ.vertices[3])); + + // (P)lus Z + Mesh PZ = new Mesh(); + + PZ.Add(new Vertex("-X-Y+Z", -size.X / 2.0f, -size.Y / 2.0f, 0.0f)); + PZ.Add(new Vertex("+X-Y+Z", +size.X / 2.0f, -size.Y / 2.0f, 0.0f)); + PZ.Add(new Vertex("-X+Y+Z", -size.X / 2.0f, +size.Y / 2.0f, 0.0f)); + PZ.Add(new Vertex("+X+Y+Z", +size.X / 2.0f, +size.Y / 2.0f, 0.0f)); + + // Surface 5, +Z + PZ.Add(new Triangle(PZ.vertices[0], PZ.vertices[1], PZ.vertices[2])); + PZ.Add(new Triangle(PZ.vertices[2], PZ.vertices[1], PZ.vertices[3])); + + if (hollowFactor > 0) + { + float hollowFactorF = (float)hollowFactor / (float)50000; + + MZ.Add(new Vertex("-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f)); + MZ.Add(new Vertex("-X+Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f)); + MZ.Add(new Vertex("-X-Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f)); + MZ.Add(new Vertex("-X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f)); + + List innerBorders = new List(); + innerBorders.Add(4); + innerBorders.Add(5); + innerBorders.Add(6); + innerBorders.Add(7); + + InsertVertices(MZ.vertices, 4, MZ.triangles, innerBorders); + + PZ.Add(new Vertex("-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f)); + PZ.Add(new Vertex("-X+Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f)); + PZ.Add(new Vertex("-X-Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f)); + PZ.Add(new Vertex("-X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f)); + + innerBorders = new List(); + innerBorders.Add(4); + innerBorders.Add(5); + innerBorders.Add(6); + innerBorders.Add(7); + + InsertVertices(PZ.vertices, 4, PZ.triangles, innerBorders); + + } + + foreach (Vertex v in PZ.vertices) + { + v.point.Z = size.Z / 2.0f; + } + foreach (Vertex v in MZ.vertices) + { + v.point.Z = -size.Z / 2.0f; + } + + foreach (Triangle t in MZ.triangles) + { + PhysicsVector n = t.getNormal(); + if (n.Z > 0.0) + t.invertNormal(); + } + + foreach (Triangle t in PZ.triangles) + { + PhysicsVector n = t.getNormal(); + if (n.Z < 0.0) + t.invertNormal(); + } + + Mesh result = new Mesh(); + result.Append(MZ); + result.Append(PZ); + + return result; + } + + static Mesh CreateBoxMesh(PrimitiveBaseShape primShape, PhysicsVector size) + { + Mesh result = new Mesh(); + + + + Mesh MeshX = Meshmerizer.CreateBoxMeshX(primShape, size); + Mesh MeshY = Meshmerizer.CreateBoxMeshY(primShape, size); + Mesh MeshZ = Meshmerizer.CreateBoxMeshZ(primShape, size); + + result.Append(MeshX); + result.Append(MeshY); + result.Append(MeshZ); + + 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.point.X; + uy = t.v1.point.Y; + uz = t.v1.point.Z; + + vx = t.v2.point.X; + vy = t.v2.point.Y; + vz = t.v2.point.Z; + + wx = t.v3.point.X; + wy = t.v3.point.Y; + wz = t.v3.point.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(PrimitiveBaseShape primShape, PhysicsVector size) + { + Mesh mesh = null; + + switch (primShape.ProfileShape) + { + case ProfileShape.Square: + mesh=CreateBoxMesh(primShape, size); + CalcNormals(mesh); + break; + default: + mesh=null; + break; + } + + return mesh; + + } + } +} + diff --git "a/OpenSim/Region/Physics/OdePlugin/Meshing\\/HelperTypes.cs" "b/OpenSim/Region/Physics/OdePlugin/Meshing\\/HelperTypes.cs" deleted file mode 100644 index 3d40c04..0000000 --- "a/OpenSim/Region/Physics/OdePlugin/Meshing\\/HelperTypes.cs" +++ /dev/null @@ -1,279 +0,0 @@ -using System; -using System.Globalization; -using System.Diagnostics; -using System.Collections.Generic; - -using OpenSim.Region.Physics.Manager; - -public class Vertex : IComparable -{ - public String name; - public PhysicsVector point; - - public Vertex(String name, float x, float y, float z) - { - this.name = name; - point = new PhysicsVector(x, y, z); - } - - public int CompareTo(Vertex other) - { - if (point.X < other.point.X) - return -1; - - if (point.X > other.point.X) - return 1; - - if (point.Y < other.point.Y) - return -1; - - if (point.Y > other.point.Y) - return 1; - - if (point.Z < other.point.Z) - return -1; - - if (point.Z > other.point.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 class Simplex : IComparable -{ - public Vertex v1; - public Vertex v2; - - public Simplex(Vertex _v1, Vertex _v2) - { - // Presort indices to make sorting (comparing) easier - if (_v1 > _v2) - { - v1 = _v1; - v2 = _v2; - } - else - { - v1 = _v2; - v2 = _v1; - } - } - - public int CompareTo(Simplex other) - { - if (v1 > other.v1) - { - return 1; - } - if (v1 < other.v1) - { - return -1; - } - - if (v2 > other.v2) - { - return 1; - } - if (v2 < other.v2) - { - return -1; - } - - return 0; - } - -}; - -public class Triangle -{ - public Vertex v1; - public Vertex v2; - public Vertex v3; - - float radius_square; - float cx; - 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 - this.cx; - dy = y - this.cy; - - dd = dx * dx + dy * dy; - if (dd < this.radius_square) - return true; - else - return false; - } - - - 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.point.X; - p1y = v1.point.Y; - - p2x = v2.point.X; - p2y = v2.point.Y; - - p3x = v3.point.X; - p3y = v3.point.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; - } - - this.cy = (float)(z / n); - - if (v2x != 0.0) - { - this.cx = (float)((c2 - v2y * this.cy) / v2x); - } - else if (v1x != 0.0) - { - this.cx = (float)((c1 - v1y * this.cy) / v1x); - } - else - { - Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */ - } - - rx = (p1x - this.cx); - ry = (p1y - this.cy); - - this.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.point.X.ToString(nfi) + "," + v1.point.Y.ToString(nfi) + "," + v1.point.Z.ToString(nfi) + ">"; - String s2 = "<" + v2.point.X.ToString(nfi) + "," + v2.point.Y.ToString(nfi) + "," + v2.point.Z.ToString(nfi) + ">"; - String s3 = "<" + v3.point.X.ToString(nfi) + "," + v3.point.Y.ToString(nfi) + "," + v3.point.Z.ToString(nfi) + ">"; - - return s1 + ";" + s2 + ";" + s3; - - } - - public PhysicsVector getNormal() - { - // Vertices - - // Vectors for edges - PhysicsVector e1; - PhysicsVector e2; - - e1 = new PhysicsVector(v1.point.X - v2.point.X, v1.point.Y - v2.point.Y, v1.point.Z - v2.point.Z); - e2 = new PhysicsVector(v1.point.X - v3.point.X, v1.point.Y - v3.point.Y, v1.point.Z - v3.point.Z); - - // Cross product for normal - PhysicsVector n = new PhysicsVector(); - float nx, ny, nz; - n.X = e1.Y * e2.Z - e1.Z * e2.Y; - n.Y = e1.Z * e2.X - e1.X * e2.Z; - n.Z = e1.X * e2.Y - e1.Y * e2.X; - - // Length - float l = (float)Math.Sqrt(n.X * n.X + n.Y * n.Y + n.Z * n.Z); - - // Normalized "normal" - n.X /= l; - n.Y /= l; - n.Z /= l; - - return n; - } - - public void invertNormal() - { - Vertex vt; - vt = v1; - v1 = v2; - v2 = vt; - } -} - diff --git "a/OpenSim/Region/Physics/OdePlugin/Meshing\\/Meshmerizer.cs" "b/OpenSim/Region/Physics/OdePlugin/Meshing\\/Meshmerizer.cs" deleted file mode 100644 index 28dca41..0000000 --- "a/OpenSim/Region/Physics/OdePlugin/Meshing\\/Meshmerizer.cs" +++ /dev/null @@ -1,560 +0,0 @@ -using System; -using System.Globalization; -using System.Diagnostics; -using System.Collections.Generic; -using System.Text; -using System.Runtime.InteropServices; - -using OpenSim.Framework.Types; -using OpenSim.Region.Physics.Manager; - -namespace OpenSim.Region.Physics.OdePlugin -{ - public class Mesh - { - public List vertices; - public List triangles; - - public float[] normals; - - public Mesh() - { - vertices = new List(); - triangles = new List(); - } - - 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 float[] getVertexListAsFloat() - { - float[] result = new float[vertices.Count * 3]; - for (int i = 0; i < vertices.Count; i++) - { - Vertex v = vertices[i]; - PhysicsVector point = v.point; - result[3 * i + 0] = point.X; - result[3 * i + 1] = point.Y; - result[3 * i + 2] = point.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); - - } - } - - - - public class Meshmerizer - { - - static List FindInfluencedTriangles(List triangles, Vertex v) - { - List influenced = new List(); - foreach (Triangle t in triangles) - { - float dx, dy; - - if (t.isInCircle(v.point.X, v.point.Y)) - { - influenced.Add(t); - } - } - return influenced; - } - - - static void InsertVertices(List vertices, int usedForSeed, List triangles, List innerBorders) - { - // 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]; - 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 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 - 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]); - triangles.Add(t); - } - } - - // At this point all vertices should be inserted into the mesh - // But the areas, that should be kept free still are filled with triangles - // We have to remove them. For this we have a list of indices to vertices. - // Each triangle that solemnly constists of vertices from the inner border - // are deleted - - List innerTriangles = new List(); - foreach (Triangle t in triangles) - { - if ( - innerBorders.Contains(vertices.IndexOf(t.v1)) - && innerBorders.Contains(vertices.IndexOf(t.v2)) - && innerBorders.Contains(vertices.IndexOf(t.v3)) - ) - innerTriangles.Add(t); - } - foreach (Triangle t in innerTriangles) - { - triangles.Remove(t); - } - } - - - static Mesh CreateBoxMeshX(PrimitiveBaseShape primShape, PhysicsVector size) - // Builds the x (+ and -) surfaces of a box shaped prim - { - UInt16 hollowFactor = primShape.ProfileHollow; - Mesh meshMX = new Mesh(); - - - // Surface 0, -X - meshMX.Add(new Vertex("-X-Y-Z", -size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); - meshMX.Add(new Vertex("-X+Y-Z", -size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); - meshMX.Add(new Vertex("-X-Y+Z", -size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f)); - meshMX.Add(new Vertex("-X+Y+Z", -size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f)); - - meshMX.Add(new Triangle(meshMX.vertices[0], meshMX.vertices[2], meshMX.vertices[1])); - meshMX.Add(new Triangle(meshMX.vertices[1], meshMX.vertices[2], meshMX.vertices[3])); - - - Mesh meshPX = new Mesh(); - // Surface 1, +X - meshPX.Add(new Vertex("+X-Y-Z", +size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); - meshPX.Add(new Vertex("+X+Y-Z", +size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); - meshPX.Add(new Vertex("+X-Y+Z", +size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f)); - meshPX.Add(new Vertex("+X+Y+Z", +size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f)); - - - meshPX.Add(new Triangle(meshPX.vertices[0], meshPX.vertices[1], meshPX.vertices[2])); - meshPX.Add(new Triangle(meshPX.vertices[2], meshPX.vertices[1], meshPX.vertices[3])); - - - if (hollowFactor > 0) - { - float hollowFactorF = (float)hollowFactor / (float)50000; - - Vertex IPP; - Vertex IPM; - Vertex IMP; - Vertex IMM; - - IPP = new Vertex("Inner-X+Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); - IPM = new Vertex("Inner-X+Y-Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); - IMP = new Vertex("Inner-X-Y+Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); - IMM = new Vertex("Inner-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); - - meshMX.Add(IPP); - meshMX.Add(IPM); - meshMX.Add(IMP); - meshMX.Add(IMM); - - meshMX.Add(new Triangle(IPP, IMP, IPM)); - meshMX.Add(new Triangle(IPM, IMP, IMM)); - - foreach (Triangle t in meshMX.triangles) - { - PhysicsVector n = t.getNormal(); - } - - - - IPP = new Vertex("Inner+X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); - IPM = new Vertex("Inner+X+Y-Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); - IMP = new Vertex("Inner+X-Y+Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); - IMM = new Vertex("Inner+X-Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); - - meshPX.Add(IPP); - meshPX.Add(IPM); - meshPX.Add(IMP); - meshPX.Add(IMM); - - meshPX.Add(new Triangle(IPP, IPM, IMP)); - meshPX.Add(new Triangle(IMP, IPM, IMM)); - - foreach (Triangle t in meshPX.triangles) - { - PhysicsVector n = t.getNormal(); - } - } - - Mesh result = new Mesh(); - result.Append(meshMX); - result.Append(meshPX); - - return result; - } - - - - static Mesh CreateBoxMeshY(PrimitiveBaseShape primShape, PhysicsVector size) - // Builds the y (+ and -) surfaces of a box shaped prim - { - UInt16 hollowFactor = primShape.ProfileHollow; - - // (M)inus Y - Mesh MeshMY = new Mesh(); - MeshMY.Add(new Vertex("-X-Y-Z", -size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); - MeshMY.Add(new Vertex("+X-Y-Z", +size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); - MeshMY.Add(new Vertex("-X-Y+Z", -size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f)); - MeshMY.Add(new Vertex("+X-Y+Z", +size.X / 2.0f, -size.Y / 2.0f, +size.Z / 2.0f)); - - MeshMY.Add(new Triangle(MeshMY.vertices[0], MeshMY.vertices[1], MeshMY.vertices[2])); - MeshMY.Add(new Triangle(MeshMY.vertices[2], MeshMY.vertices[1], MeshMY.vertices[3])); - - // (P)lus Y - Mesh MeshPY = new Mesh(); - - MeshPY.Add(new Vertex("-X+Y-Z", -size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); - MeshPY.Add(new Vertex("+X+Y-Z", +size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); - MeshPY.Add(new Vertex("-X+Y+Z", -size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f)); - MeshPY.Add(new Vertex("+X+Y+Z", +size.X / 2.0f, +size.Y / 2.0f, +size.Z / 2.0f)); - - MeshPY.Add(new Triangle(MeshPY.vertices[1], MeshPY.vertices[0], MeshPY.vertices[2])); - MeshPY.Add(new Triangle(MeshPY.vertices[1], MeshPY.vertices[2], MeshPY.vertices[3])); - - if (hollowFactor > 0) - { - float hollowFactorF = (float)hollowFactor / (float)50000; - - Vertex IPP; - Vertex IPM; - Vertex IMP; - Vertex IMM; - - IPP = new Vertex("Inner+X-Y+Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); - IPM = new Vertex("Inner+X-Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); - IMP = new Vertex("Inner-X-Y+Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); - IMM = new Vertex("Inner-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); - - MeshMY.Add(IPP); - MeshMY.Add(IPM); - MeshMY.Add(IMP); - MeshMY.Add(IMM); - - MeshMY.Add(new Triangle(IPP, IPM, IMP)); - MeshMY.Add(new Triangle(IMP, IPM, IMM)); - - foreach (Triangle t in MeshMY.triangles) - { - PhysicsVector n = t.getNormal(); - } - - - - IPP = new Vertex("Inner+X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); - IPM=new Vertex("Inner+X+Y-Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); - IMP=new Vertex("Inner-X+Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, +size.Z / 2.0f); - IMM=new Vertex("Inner-X+Y-Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, -size.Z / 2.0f); - - MeshPY.Add(IPP); - MeshPY.Add(IPM); - MeshPY.Add(IMP); - MeshPY.Add(IMM); - - MeshPY.Add(new Triangle(IPM, IPP, IMP)); - MeshPY.Add(new Triangle(IMP, IMM, IPM)); - - foreach (Triangle t in MeshPY.triangles) - { - PhysicsVector n = t.getNormal(); - } - - - - } - - - Mesh result = new Mesh(); - result.Append(MeshMY); - result.Append(MeshPY); - - return result; - } - - static Mesh CreateBoxMeshZ(PrimitiveBaseShape primShape, PhysicsVector size) - // Builds the z (+ and -) surfaces of a box shaped prim - { - UInt16 hollowFactor = primShape.ProfileHollow; - - // Base, i.e. outer shape - // (M)inus Z - Mesh MZ = new Mesh(); - - MZ.Add(new Vertex("-X-Y-Z", -size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); - MZ.Add(new Vertex("+X-Y-Z", +size.X / 2.0f, -size.Y / 2.0f, -size.Z / 2.0f)); - MZ.Add(new Vertex("-X+Y-Z", -size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); - MZ.Add(new Vertex("+X+Y-Z", +size.X / 2.0f, +size.Y / 2.0f, -size.Z / 2.0f)); - - - MZ.Add(new Triangle(MZ.vertices[1], MZ.vertices[0], MZ.vertices[2])); - MZ.Add(new Triangle(MZ.vertices[1], MZ.vertices[2], MZ.vertices[3])); - - // (P)lus Z - Mesh PZ = new Mesh(); - - PZ.Add(new Vertex("-X-Y+Z", -size.X / 2.0f, -size.Y / 2.0f, 0.0f)); - PZ.Add(new Vertex("+X-Y+Z", +size.X / 2.0f, -size.Y / 2.0f, 0.0f)); - PZ.Add(new Vertex("-X+Y+Z", -size.X / 2.0f, +size.Y / 2.0f, 0.0f)); - PZ.Add(new Vertex("+X+Y+Z", +size.X / 2.0f, +size.Y / 2.0f, 0.0f)); - - // Surface 5, +Z - PZ.Add(new Triangle(PZ.vertices[0], PZ.vertices[1], PZ.vertices[2])); - PZ.Add(new Triangle(PZ.vertices[2], PZ.vertices[1], PZ.vertices[3])); - - if (hollowFactor > 0) - { - float hollowFactorF = (float)hollowFactor / (float)50000; - - MZ.Add(new Vertex("-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f)); - MZ.Add(new Vertex("-X+Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f)); - MZ.Add(new Vertex("-X-Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f)); - MZ.Add(new Vertex("-X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f)); - - List innerBorders = new List(); - innerBorders.Add(4); - innerBorders.Add(5); - innerBorders.Add(6); - innerBorders.Add(7); - - InsertVertices(MZ.vertices, 4, MZ.triangles, innerBorders); - - PZ.Add(new Vertex("-X-Y-Z", -size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f)); - PZ.Add(new Vertex("-X+Y-Z", +size.X * hollowFactorF / 2.0f, -size.Y * hollowFactorF / 2.0f, 0.0f)); - PZ.Add(new Vertex("-X-Y+Z", -size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f)); - PZ.Add(new Vertex("-X+Y+Z", +size.X * hollowFactorF / 2.0f, +size.Y * hollowFactorF / 2.0f, 0.0f)); - - innerBorders = new List(); - innerBorders.Add(4); - innerBorders.Add(5); - innerBorders.Add(6); - innerBorders.Add(7); - - InsertVertices(PZ.vertices, 4, PZ.triangles, innerBorders); - - } - - foreach (Vertex v in PZ.vertices) - { - v.point.Z = size.Z / 2.0f; - } - foreach (Vertex v in MZ.vertices) - { - v.point.Z = -size.Z / 2.0f; - } - - foreach (Triangle t in MZ.triangles) - { - PhysicsVector n = t.getNormal(); - if (n.Z > 0.0) - t.invertNormal(); - } - - foreach (Triangle t in PZ.triangles) - { - PhysicsVector n = t.getNormal(); - if (n.Z < 0.0) - t.invertNormal(); - } - - Mesh result = new Mesh(); - result.Append(MZ); - result.Append(PZ); - - return result; - } - - static Mesh CreateBoxMesh(PrimitiveBaseShape primShape, PhysicsVector size) - { - Mesh result = new Mesh(); - - - - Mesh MeshX = Meshmerizer.CreateBoxMeshX(primShape, size); - Mesh MeshY = Meshmerizer.CreateBoxMeshY(primShape, size); - Mesh MeshZ = Meshmerizer.CreateBoxMeshZ(primShape, size); - - result.Append(MeshX); - result.Append(MeshY); - result.Append(MeshZ); - - 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.point.X; - uy = t.v1.point.Y; - uz = t.v1.point.Z; - - vx = t.v2.point.X; - vy = t.v2.point.Y; - vz = t.v2.point.Z; - - wx = t.v3.point.X; - wy = t.v3.point.Y; - wz = t.v3.point.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(PrimitiveBaseShape primShape, PhysicsVector size) - { - Mesh mesh = null; - - switch (primShape.ProfileShape) - { - case ProfileShape.Square: - mesh=CreateBoxMesh(primShape, size); - CalcNormals(mesh); - break; - default: - mesh=null; - break; - } - - return mesh; - - } - } -} - -- cgit v1.1