diff --git a/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs b/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs index 293825779e..5dc1e789ce 100644 --- a/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs +++ b/OpenSim/Region/Physics/UbitMeshing/HelperTypes.cs @@ -256,9 +256,9 @@ public class Vertex : IComparable // settings your machine works with. Unusable for a machine readable file format :-( NumberFormatInfo nfi = new NumberFormatInfo(); nfi.NumberDecimalSeparator = "."; - nfi.NumberDecimalDigits = 3; + nfi.NumberDecimalDigits = 6; - String s1 = X.ToString("N2", nfi) + " " + Y.ToString("N2", nfi) + " " + Z.ToString("N2", nfi); + String s1 = X.ToString(nfi) + " " + Y.ToString(nfi) + " " + Z.ToString(nfi); return s1; } diff --git a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs index fa069265c5..04188931e3 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs @@ -205,34 +205,21 @@ namespace OpenSim.Region.Physics.Meshing } - private float fRound(float f) - { - int i; - if (f == 0f) - return f; - else if (f > 0f) - i = (int)(1e5f * f + 0.5f); - else - i = (int)(1e5f * f - 0.5f); - - return ((float)i * 1e-5f); - } - public void Add(Triangle triangle) { if (m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) throw new NotSupportedException("Attempt to Add to a pinned Mesh"); - // round down - triangle.v1.X = fRound(triangle.v1.X); - triangle.v1.Y = fRound(triangle.v1.Y); - triangle.v1.Z = fRound(triangle.v1.Z); - triangle.v2.X = fRound(triangle.v2.X); - triangle.v2.Y = fRound(triangle.v2.Y); - triangle.v2.Z = fRound(triangle.v2.Z); - triangle.v3.X = fRound(triangle.v3.X); - triangle.v3.Y = fRound(triangle.v3.Y); - triangle.v3.Z = fRound(triangle.v3.Z); + + triangle.v1.X = (float)Math.Round(triangle.v1.X, 6); + triangle.v1.Y = (float)Math.Round(triangle.v1.Y, 6); + triangle.v1.Z = (float)Math.Round(triangle.v1.Z, 6); + triangle.v2.X = (float)Math.Round(triangle.v2.X, 6); + triangle.v2.Y = (float)Math.Round(triangle.v2.Y, 6); + triangle.v2.Z = (float)Math.Round(triangle.v2.Z, 6); + triangle.v3.X = (float)Math.Round(triangle.v3.X, 6); + triangle.v3.Y = (float)Math.Round(triangle.v3.Y, 6); + triangle.v3.Z = (float)Math.Round(triangle.v3.Z, 6); if ((triangle.v1.X == triangle.v2.X && triangle.v1.Y == triangle.v2.Y && triangle.v1.Z == triangle.v2.Z) || (triangle.v1.X == triangle.v3.X && triangle.v1.Y == triangle.v3.Y && triangle.v1.Z == triangle.v3.Z) diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index 00cbfbd3c9..c131c6f9b6 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs @@ -816,15 +816,31 @@ namespace OpenSim.Region.Physics.Meshing float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f; float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f; + + if (profileBegin < 0.0f) + profileBegin = 0.0f; + + if (profileEnd < 0.02f) + profileEnd = 0.02f; + else if (profileEnd > 1.0f) + profileEnd = 1.0f; + + if (profileBegin >= profileEnd) + profileBegin = profileEnd - 0.02f; + float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f; if (profileHollow > 0.95f) profileHollow = 0.95f; - + int sides = 4; LevelOfDetail iLOD = (LevelOfDetail)lod; - if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) + byte profshape = (byte)(primShape.ProfileCurve & 0x07); + + if (profshape == (byte)ProfileShape.EquilateralTriangle + || profshape == (byte)ProfileShape.IsometricTriangle + || profshape == (byte)ProfileShape.RightTriangle) sides = 3; - else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) + else if (profshape == (byte)ProfileShape.Circle) { switch (iLOD) { @@ -835,7 +851,7 @@ namespace OpenSim.Region.Physics.Meshing default: sides = 24; break; } } - else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) + else if (profshape == (byte)ProfileShape.HalfCircle) { // half circle, prim is a sphere switch (iLOD) { @@ -865,10 +881,15 @@ namespace OpenSim.Region.Physics.Meshing else if (primShape.HollowShape == HollowShape.Square) hollowSides = 4; else if (primShape.HollowShape == HollowShape.Triangle) - hollowSides = 3; + { + if (profshape == (byte)ProfileShape.HalfCircle) + hollowSides = 6; + else + hollowSides = 3; + } primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides); - + if (primMesh.errorMessage != null) if (primMesh.errorMessage.Length > 0) m_log.Error("[ERROR] " + primMesh.errorMessage); @@ -880,17 +901,11 @@ namespace OpenSim.Region.Physics.Meshing if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible) { - primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10; - primMesh.twistEnd = primShape.PathTwist * 18 / 10; + primMesh.twistBegin = (primShape.PathTwistBegin * 18) / 10; + primMesh.twistEnd = (primShape.PathTwist * 18) / 10; primMesh.taperX = pathScaleX; primMesh.taperY = pathScaleY; - if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) - { - ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); - if (profileBegin < 0.0f) profileBegin = 0.0f; - if (profileEnd > 1.0f) profileEnd = 1.0f; - } #if SPAM m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString()); #endif @@ -911,17 +926,11 @@ namespace OpenSim.Region.Physics.Meshing primMesh.radius = 0.01f * primShape.PathRadiusOffset; primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions; primMesh.skew = 0.01f * primShape.PathSkew; - primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10; - primMesh.twistEnd = primShape.PathTwist * 36 / 10; + primMesh.twistBegin = (primShape.PathTwistBegin * 36) / 10; + primMesh.twistEnd = (primShape.PathTwist * 36) / 10; primMesh.taperX = primShape.PathTaperX * 0.01f; primMesh.taperY = primShape.PathTaperY * 0.01f; - if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) - { - ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); - if (profileBegin < 0.0f) profileBegin = 0.0f; - if (profileEnd > 1.0f) profileEnd = 1.0f; - } #if SPAM m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString()); #endif @@ -1031,14 +1040,19 @@ namespace OpenSim.Region.Physics.Meshing public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) { - return CreateMesh(primName, primShape, size, lod, false,false,false,false); + return CreateMesh(primName, primShape, size, lod, false,false,false); } public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) { - return CreateMesh(primName, primShape, size, lod, false,false,false,false); + return CreateMesh(primName, primShape, size, lod, false,false,false); } + public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache, bool convex, bool forOde) + { + return CreateMesh(primName, primShape, size, lod, false, false, false); + } + public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) { Mesh mesh = null; @@ -1080,7 +1094,7 @@ namespace OpenSim.Region.Physics.Meshing private static Vector3 m_MeshUnitSize = new Vector3(1.0f, 1.0f, 1.0f); - public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache, bool convex, bool forOde) + public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex, bool forOde) { #if SPAM m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName); diff --git a/OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs b/OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs index 4049ee1598..8eb136bff4 100644 --- a/OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs +++ b/OpenSim/Region/Physics/UbitMeshing/PrimMesher.cs @@ -225,26 +225,6 @@ namespace PrimMesher } } - public struct UVCoord - { - public float U; - public float V; - - - public UVCoord(float u, float v) - { - this.U = u; - this.V = v; - } - - public UVCoord Flip() - { - this.U = 1.0f - this.U; - this.V = 1.0f - this.V; - return this; - } - } - public struct Face { public int primFace; @@ -254,16 +234,6 @@ namespace PrimMesher public int v2; public int v3; - //normals - public int n1; - public int n2; - public int n3; - - // uvs - public int uv1; - public int uv2; - public int uv3; - public Face(int v1, int v2, int v3) { primFace = 0; @@ -272,31 +242,6 @@ namespace PrimMesher this.v2 = v2; this.v3 = v3; - this.n1 = 0; - this.n2 = 0; - this.n3 = 0; - - this.uv1 = 0; - this.uv2 = 0; - this.uv3 = 0; - - } - - public Face(int v1, int v2, int v3, int n1, int n2, int n3) - { - primFace = 0; - - this.v1 = v1; - this.v2 = v2; - this.v3 = v3; - - this.n1 = n1; - this.n2 = n2; - this.n3 = n3; - - this.uv1 = 0; - this.uv2 = 0; - this.uv3 = 0; } public Coord SurfaceNormal(List coordList) @@ -312,96 +257,6 @@ namespace PrimMesher } } - public struct ViewerFace - { - public int primFaceNumber; - - public Coord v1; - public Coord v2; - public Coord v3; - - public int coordIndex1; - public int coordIndex2; - public int coordIndex3; - - public Coord n1; - public Coord n2; - public Coord n3; - - public UVCoord uv1; - public UVCoord uv2; - public UVCoord uv3; - - public ViewerFace(int primFaceNumber) - { - this.primFaceNumber = primFaceNumber; - - this.v1 = new Coord(); - this.v2 = new Coord(); - this.v3 = new Coord(); - - this.coordIndex1 = this.coordIndex2 = this.coordIndex3 = -1; // -1 means not assigned yet - - this.n1 = new Coord(); - this.n2 = new Coord(); - this.n3 = new Coord(); - - this.uv1 = new UVCoord(); - this.uv2 = new UVCoord(); - this.uv3 = new UVCoord(); - } - - public void Scale(float x, float y, float z) - { - this.v1.X *= x; - this.v1.Y *= y; - this.v1.Z *= z; - - this.v2.X *= x; - this.v2.Y *= y; - this.v2.Z *= z; - - this.v3.X *= x; - this.v3.Y *= y; - this.v3.Z *= z; - } - - public void AddPos(float x, float y, float z) - { - this.v1.X += x; - this.v2.X += x; - this.v3.X += x; - - this.v1.Y += y; - this.v2.Y += y; - this.v3.Y += y; - - this.v1.Z += z; - this.v2.Z += z; - this.v3.Z += z; - } - - public void AddRot(Quat q) - { - this.v1 *= q; - this.v2 *= q; - this.v3 *= q; - - this.n1 *= q; - this.n2 *= q; - this.n3 *= q; - } - - public void CalcSurfaceNormal() - { - - Coord edge1 = new Coord(this.v2.X - this.v1.X, this.v2.Y - this.v1.Y, this.v2.Z - this.v1.Z); - Coord edge2 = new Coord(this.v3.X - this.v1.X, this.v3.Y - this.v1.Y, this.v3.Z - this.v1.Z); - - this.n1 = this.n2 = this.n3 = Coord.Cross(edge1, edge2).Normalize(); - } - } - internal struct Angle { internal float angle; @@ -428,14 +283,6 @@ namespace PrimMesher new Angle(1.0f, 1.0f, 0.0f) }; - private static Coord[] normals3 = - { - new Coord(0.25f, 0.4330127019f, 0.0f).Normalize(), - new Coord(-0.5f, 0.0f, 0.0f).Normalize(), - new Coord(0.25f, -0.4330127019f, 0.0f).Normalize(), - new Coord(0.25f, 0.4330127019f, 0.0f).Normalize() - }; - private static Angle[] angles4 = { new Angle(0.0f, 1.0f, 0.0f), @@ -445,13 +292,32 @@ namespace PrimMesher new Angle(1.0f, 1.0f, 0.0f) }; - private static Coord[] normals4 = + private static Angle[] angles6 = { - new Coord(0.5f, 0.5f, 0.0f).Normalize(), - new Coord(-0.5f, 0.5f, 0.0f).Normalize(), - new Coord(-0.5f, -0.5f, 0.0f).Normalize(), - new Coord(0.5f, -0.5f, 0.0f).Normalize(), - new Coord(0.5f, 0.5f, 0.0f).Normalize() + new Angle(0.0f, 1.0f, 0.0f), + new Angle(0.16666666666666667f, 0.5f, 0.8660254037844386f), + new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), + new Angle(0.5f, -1.0f, 0.0f), + new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), + new Angle(0.83333333333333326f, 0.5f, -0.86602540378443904f), + new Angle(1.0f, 1.0f, 0.0f) + }; + + private static Angle[] angles12 = + { + new Angle(0.0f, 1.0f, 0.0f), + new Angle(0.083333333333333329f, 0.86602540378443871f, 0.5f), + new Angle(0.16666666666666667f, 0.5f, 0.8660254037844386f), + new Angle(0.25f, 0.0f, 1.0f), + new Angle(0.33333333333333333f, -0.5f, 0.86602540378443871f), + new Angle(0.41666666666666663f, -0.86602540378443849f, 0.5f), + new Angle(0.5f, -1.0f, 0.0f), + new Angle(0.58333333333333326f, -0.86602540378443882f, -0.5f), + new Angle(0.66666666666666667f, -0.5f, -0.86602540378443837f), + new Angle(0.75f, 0.0f, -1.0f), + new Angle(0.83333333333333326f, 0.5f, -0.86602540378443904f), + new Angle(0.91666666666666663f, 0.86602540378443837f, -0.5f), + new Angle(1.0f, 1.0f, 0.0f) }; private static Angle[] angles24 = @@ -503,56 +369,72 @@ namespace PrimMesher } internal List angles; - internal List normals; - internal void makeAngles(int sides, float startAngle, float stopAngle) + internal void makeAngles(int sides, float startAngle, float stopAngle, bool hasCut) { angles = new List(); - normals = new List(); - double twoPi = System.Math.PI * 2.0; - float twoPiInv = 1.0f / (float)twoPi; + const double twoPi = System.Math.PI * 2.0; + const float twoPiInv = (float)(1.0d / twoPi); if (sides < 1) throw new Exception("number of sides not greater than zero"); if (stopAngle <= startAngle) throw new Exception("stopAngle not greater than startAngle"); - if ((sides == 3 || sides == 4 || sides == 24)) + if ((sides == 3 || sides == 4 || sides == 6 || sides == 12 || sides == 24)) { startAngle *= twoPiInv; stopAngle *= twoPiInv; Angle[] sourceAngles; - if (sides == 3) - sourceAngles = angles3; - else if (sides == 4) - sourceAngles = angles4; - else sourceAngles = angles24; + switch (sides) + { + case 3: + sourceAngles = angles3; + break; + case 4: + sourceAngles = angles4; + break; + case 6: + sourceAngles = angles6; + break; + case 12: + sourceAngles = angles12; + break; + default: + sourceAngles = angles24; + break; + } int startAngleIndex = (int)(startAngle * sides); int endAngleIndex = sourceAngles.Length - 1; - if (stopAngle < 1.0f) - endAngleIndex = (int)(stopAngle * sides) + 1; - if (endAngleIndex == startAngleIndex) - endAngleIndex++; - for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++) + if (hasCut) { - angles.Add(sourceAngles[angleIndex]); - if (sides == 3) - normals.Add(normals3[angleIndex]); - else if (sides == 4) - normals.Add(normals4[angleIndex]); + if (stopAngle < 1.0f) + endAngleIndex = (int)(stopAngle * sides) + 1; + if (endAngleIndex == startAngleIndex) + endAngleIndex++; + + for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++) + { + angles.Add(sourceAngles[angleIndex]); + } + + if (startAngle > 0.0f) + angles[0] = interpolatePoints(startAngle, angles[0], angles[1]); + + if (stopAngle < 1.0f) + { + int lastAngleIndex = angles.Count - 1; + angles[lastAngleIndex] = interpolatePoints(stopAngle, angles[lastAngleIndex - 1], angles[lastAngleIndex]); + } } - - if (startAngle > 0.0f) - angles[0] = interpolatePoints(startAngle, angles[0], angles[1]); - - if (stopAngle < 1.0f) + else { - int lastAngleIndex = angles.Count - 1; - angles[lastAngleIndex] = interpolatePoints(stopAngle, angles[lastAngleIndex - 1], angles[lastAngleIndex]); + for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex; angleIndex++) + angles.Add(sourceAngles[angleIndex]); } } else @@ -618,20 +500,10 @@ namespace PrimMesher public List coords; public List faces; - public List vertexNormals; - public List us; - public List faceUVs; - public List faceNumbers; // use these for making individual meshes for each prim face public List outerCoordIndices = null; public List hollowCoordIndices = null; - public List cut1CoordIndices = null; - public List cut2CoordIndices = null; - - public Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f); - public Coord cutNormal1 = new Coord(); - public Coord cutNormal2 = new Coord(); public int numOuterVerts = 0; public int numHollowVerts = 0; @@ -639,7 +511,6 @@ namespace PrimMesher public int outerFaceNumber = -1; public int hollowFaceNumber = -1; - public bool calcVertexNormals = false; public int bottomFaceNumber = 0; public int numPrimFaces = 0; @@ -647,40 +518,19 @@ namespace PrimMesher { this.coords = new List(); this.faces = new List(); - this.vertexNormals = new List(); - this.us = new List(); - this.faceUVs = new List(); - this.faceNumbers = new List(); } - public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals) + public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool hasProfileCut, bool createFaces) { - this.calcVertexNormals = calcVertexNormals; + const float halfSqr2 = 0.7071067811866f; + this.coords = new List(); this.faces = new List(); - this.vertexNormals = new List(); - this.us = new List(); - this.faceUVs = new List(); - this.faceNumbers = new List(); - - Coord center = new Coord(0.0f, 0.0f, 0.0f); List hollowCoords = new List(); - List hollowNormals = new List(); - List hollowUs = new List(); - - if (calcVertexNormals) - { - this.outerCoordIndices = new List(); - this.hollowCoordIndices = new List(); - this.cut1CoordIndices = new List(); - this.cut2CoordIndices = new List(); - } bool hasHollow = (hollow > 0.0f); - bool hasProfileCut = (profileStart > 0.0f || profileEnd < 1.0f); - AngleList angles = new AngleList(); AngleList hollowAngles = new AngleList(); @@ -688,14 +538,14 @@ namespace PrimMesher float yScale = 0.5f; if (sides == 4) // corners of a square are sqrt(2) from center { - xScale = 0.707107f; - yScale = 0.707107f; + xScale = halfSqr2; + yScale = halfSqr2; } float startAngle = profileStart * twoPi; float stopAngle = profileEnd * twoPi; - try { angles.makeAngles(sides, startAngle, stopAngle); } + try { angles.makeAngles(sides, startAngle, stopAngle,hasProfileCut); } catch (Exception ex) { @@ -707,6 +557,9 @@ namespace PrimMesher this.numOuterVerts = angles.angles.Count; + Angle angle; + Coord newVert = new Coord(); + // flag to create as few triangles as possible for 3 or 4 side profile bool simpleFace = (sides < 5 && !hasHollow && !hasProfileCut); @@ -716,7 +569,7 @@ namespace PrimMesher hollowAngles = angles; else { - try { hollowAngles.makeAngles(hollowSides, startAngle, stopAngle); } + try { hollowAngles.makeAngles(hollowSides, startAngle, stopAngle, hasProfileCut); } catch (Exception ex) { errorMessage = "makeAngles failed: Exception: " + ex.ToString() @@ -724,116 +577,48 @@ namespace PrimMesher return; } + + int numHollowAngles = hollowAngles.angles.Count; + for (int i = 0; i < numHollowAngles; i++) + { + angle = hollowAngles.angles[i]; + newVert.X = hollow * xScale * angle.X; + newVert.Y = hollow * yScale * angle.Y; + newVert.Z = 0.0f; + + hollowCoords.Add(newVert); + } } this.numHollowVerts = hollowAngles.angles.Count; } else if (!simpleFace) { + Coord center = new Coord(0.0f, 0.0f, 0.0f); this.coords.Add(center); - if (this.calcVertexNormals) - this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f)); - this.us.Add(0.0f); } - float z = 0.0f; - - Angle angle; - Coord newVert = new Coord(); - if (hasHollow && hollowSides != sides) - { - int numHollowAngles = hollowAngles.angles.Count; - for (int i = 0; i < numHollowAngles; i++) - { - angle = hollowAngles.angles[i]; - newVert.X = hollow * xScale * angle.X; - newVert.Y = hollow * yScale * angle.Y; - newVert.Z = z; - - hollowCoords.Add(newVert); - if (this.calcVertexNormals) - { - if (hollowSides < 5) - hollowNormals.Add(hollowAngles.normals[i].Invert()); - else - hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); - - if (hollowSides == 4) - hollowUs.Add(angle.angle * hollow * 0.707107f); - else - hollowUs.Add(angle.angle * hollow); - } - } - } - - int index = 0; int numAngles = angles.angles.Count; + bool hollowsame = (hasHollow && hollowSides == sides); for (int i = 0; i < numAngles; i++) { angle = angles.angles[i]; newVert.X = angle.X * xScale; newVert.Y = angle.Y * yScale; - newVert.Z = z; + newVert.Z = 0.0f; this.coords.Add(newVert); - if (this.calcVertexNormals) + if (hollowsame) { - this.outerCoordIndices.Add(this.coords.Count - 1); - - if (sides < 5) - { - this.vertexNormals.Add(angles.normals[i]); - float u = angle.angle; - this.us.Add(u); - } - else - { - this.vertexNormals.Add(new Coord(angle.X, angle.Y, 0.0f)); - this.us.Add(angle.angle); - } + newVert.X *= hollow; + newVert.Y *= hollow; + hollowCoords.Add(newVert); } - - if (hasHollow) - { - if (hollowSides == sides) - { - newVert.X *= hollow; - newVert.Y *= hollow; - newVert.Z = z; - hollowCoords.Add(newVert); - if (this.calcVertexNormals) - { - if (sides < 5) - { - hollowNormals.Add(angles.normals[i].Invert()); - } - - else - hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); - - hollowUs.Add(angle.angle * hollow); - } - } - } - else if (!simpleFace && createFaces && angle.angle > 0.0001f) - { - Face newFace = new Face(); - newFace.v1 = 0; - newFace.v2 = index; - newFace.v3 = index + 1; - - this.faces.Add(newFace); - } - index += 1; } if (hasHollow) { hollowCoords.Reverse(); - if (this.calcVertexNormals) - { - hollowNormals.Reverse(); - hollowUs.Reverse(); - } + this.coords.AddRange(hollowCoords); if (createFaces) { @@ -855,187 +640,176 @@ namespace PrimMesher newFace.v3 = numTotalVerts - coordIndex - 1; this.faces.Add(newFace); } - } - else - { - if (this.numOuterVerts < this.numHollowVerts) + if (!hasProfileCut) { - Face newFace = new Face(); - int j = 0; // j is the index for outer vertices - int maxJ = this.numOuterVerts - 1; - for (int i = 0; i < this.numHollowVerts; i++) // i is the index for inner vertices + newFace.v1 = this.numOuterVerts - 1; + newFace.v2 = 0; + newFace.v3 = this.numOuterVerts; + this.faces.Add(newFace); + + newFace.v1 = 0; + newFace.v2 = numTotalVerts - 1; + newFace.v3 = this.numOuterVerts; + this.faces.Add(newFace); + } + } + else if (this.numOuterVerts < this.numHollowVerts) + { + Face newFace = new Face(); + int j = 0; // j is the index for outer vertices + int i; + int maxJ = this.numOuterVerts - 1; + float curHollowAngle = 0; + for (i = 0; i < this.numHollowVerts; i++) // i is the index for inner vertices + { + curHollowAngle = hollowAngles.angles[i].angle; + if (j < maxJ) { - if (j < maxJ) - if (angles.angles[j + 1].angle - hollowAngles.angles[i].angle < hollowAngles.angles[i].angle - angles.angles[j].angle + 0.000001f) - { - newFace.v1 = numTotalVerts - i - 1; - newFace.v2 = j; - newFace.v3 = j + 1; + if (angles.angles[j + 1].angle - curHollowAngle < curHollowAngle - angles.angles[j].angle + 0.000001f) + { + newFace.v1 = numTotalVerts - i - 1; + newFace.v2 = j; + newFace.v3 = j + 1; + this.faces.Add(newFace); + j++; + } + } + else + { + if (1.0f - curHollowAngle < curHollowAngle - angles.angles[j].angle + 0.000001f) + break; + } - this.faces.Add(newFace); - j += 1; - } + newFace.v1 = j; + newFace.v2 = numTotalVerts - i - 2; + newFace.v3 = numTotalVerts - i - 1; - newFace.v1 = j; - newFace.v2 = numTotalVerts - i - 2; - newFace.v3 = numTotalVerts - i - 1; + this.faces.Add(newFace); + } + + if (!hasProfileCut) + { + if (i == this.numHollowVerts) + { + newFace.v1 = numTotalVerts - this.numHollowVerts; + newFace.v2 = maxJ; + newFace.v3 = 0; this.faces.Add(newFace); } - } - else // numHollowVerts < numOuterVerts - { - Face newFace = new Face(); - int j = 0; // j is the index for inner vertices - int maxJ = this.numHollowVerts - 1; - for (int i = 0; i < this.numOuterVerts; i++) + else { - if (j < maxJ) - if (hollowAngles.angles[j + 1].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[j].angle + 0.000001f) - { - newFace.v1 = i; - newFace.v2 = numTotalVerts - j - 2; - newFace.v3 = numTotalVerts - j - 1; + if (1.0f - curHollowAngle < curHollowAngle - angles.angles[maxJ].angle + 0.000001f) + { + newFace.v1 = numTotalVerts - i - 1; + newFace.v2 = maxJ; + newFace.v3 = 0; - this.faces.Add(newFace); - j += 1; - } + this.faces.Add(newFace); + } - newFace.v1 = numTotalVerts - j - 1; - newFace.v2 = i; - newFace.v3 = i + 1; + for (; i < this.numHollowVerts - 1; i++) + { + newFace.v1 = 0; + newFace.v2 = numTotalVerts - i - 2; + newFace.v3 = numTotalVerts - i - 1; + + this.faces.Add(newFace); + } + } + + newFace.v1 = 0; + newFace.v2 = numTotalVerts - this.numHollowVerts; + newFace.v3 = numTotalVerts - 1; + this.faces.Add(newFace); + } + } + else // numHollowVerts < numOuterVerts + { + Face newFace = new Face(); + int j = 0; // j is the index for inner vertices + int maxJ = this.numHollowVerts - 1; + for (int i = 0; i < this.numOuterVerts; i++) + { + if (j < maxJ) + if (hollowAngles.angles[j + 1].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[j].angle + 0.000001f) + { + newFace.v1 = i; + newFace.v2 = numTotalVerts - j - 2; + newFace.v3 = numTotalVerts - j - 1; + + this.faces.Add(newFace); + j += 1; + } + + newFace.v1 = numTotalVerts - j - 1; + newFace.v2 = i; + newFace.v3 = i + 1; + + this.faces.Add(newFace); + } + + if (!hasProfileCut) + { + int i = this.numOuterVerts - 1; + + if (hollowAngles.angles[0].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[maxJ].angle + 0.000001f) + { + newFace.v1 = 0; + newFace.v2 = numTotalVerts - maxJ - 1; + newFace.v3 = numTotalVerts - 1; this.faces.Add(newFace); } + + newFace.v1 = numTotalVerts - maxJ - 1; + newFace.v2 = i; + newFace.v3 = 0; + + this.faces.Add(newFace); } } } + + } - if (calcVertexNormals) + else if (createFaces) + { + if (simpleFace) { - foreach (Coord hc in hollowCoords) + if (sides == 3) + this.faces.Add(new Face(0, 1, 2)); + else if (sides == 4) { - this.coords.Add(hc); - hollowCoordIndices.Add(this.coords.Count - 1); + this.faces.Add(new Face(0, 1, 2)); + this.faces.Add(new Face(0, 2, 3)); } } else - this.coords.AddRange(hollowCoords); - - if (this.calcVertexNormals) { - this.vertexNormals.AddRange(hollowNormals); - this.us.AddRange(hollowUs); - + for (int i = 1; i < numAngles ; i++) + { + Face newFace = new Face(); + newFace.v1 = 0; + newFace.v2 = i; + newFace.v3 = i + 1; + this.faces.Add(newFace); + } + if (!hasProfileCut) + { + Face newFace = new Face(); + newFace.v1 = 0; + newFace.v2 = numAngles; + newFace.v3 = 1; + this.faces.Add(newFace); + } } } - if (simpleFace && createFaces) - { - if (sides == 3) - this.faces.Add(new Face(0, 1, 2)); - else if (sides == 4) - { - this.faces.Add(new Face(0, 1, 2)); - this.faces.Add(new Face(0, 2, 3)); - } - } - - if (calcVertexNormals && hasProfileCut) - { - int lastOuterVertIndex = this.numOuterVerts - 1; - - if (hasHollow) - { - this.cut1CoordIndices.Add(0); - this.cut1CoordIndices.Add(this.coords.Count - 1); - - this.cut2CoordIndices.Add(lastOuterVertIndex + 1); - this.cut2CoordIndices.Add(lastOuterVertIndex); - - this.cutNormal1.X = this.coords[0].Y - this.coords[this.coords.Count - 1].Y; - this.cutNormal1.Y = -(this.coords[0].X - this.coords[this.coords.Count - 1].X); - - this.cutNormal2.X = this.coords[lastOuterVertIndex + 1].Y - this.coords[lastOuterVertIndex].Y; - this.cutNormal2.Y = -(this.coords[lastOuterVertIndex + 1].X - this.coords[lastOuterVertIndex].X); - } - - else - { - this.cut1CoordIndices.Add(0); - this.cut1CoordIndices.Add(1); - - this.cut2CoordIndices.Add(lastOuterVertIndex); - this.cut2CoordIndices.Add(0); - - this.cutNormal1.X = this.vertexNormals[1].Y; - this.cutNormal1.Y = -this.vertexNormals[1].X; - - this.cutNormal2.X = -this.vertexNormals[this.vertexNormals.Count - 2].Y; - this.cutNormal2.Y = this.vertexNormals[this.vertexNormals.Count - 2].X; - - } - this.cutNormal1.Normalize(); - this.cutNormal2.Normalize(); - } - - this.MakeFaceUVs(); hollowCoords = null; - hollowNormals = null; - hollowUs = null; - - if (calcVertexNormals) - { // calculate prim face numbers - - // face number order is top, outer, hollow, bottom, start cut, end cut - // I know it's ugly but so is the whole concept of prim face numbers - - int faceNum = 1; // start with outer faces - this.outerFaceNumber = faceNum; - - int startVert = hasProfileCut && !hasHollow ? 1 : 0; - if (startVert > 0) - this.faceNumbers.Add(-1); - for (int i = 0; i < this.numOuterVerts - 1; i++) - this.faceNumbers.Add(sides < 5 && i <= sides ? faceNum++ : faceNum); - - this.faceNumbers.Add(hasProfileCut ? -1 : faceNum++); - - if (sides > 4 && (hasHollow || hasProfileCut)) - faceNum++; - - if (sides < 5 && (hasHollow || hasProfileCut) && this.numOuterVerts < sides) - faceNum++; - - if (hasHollow) - { - for (int i = 0; i < this.numHollowVerts; i++) - this.faceNumbers.Add(faceNum); - - this.hollowFaceNumber = faceNum++; - } - - this.bottomFaceNumber = faceNum++; - - if (hasHollow && hasProfileCut) - this.faceNumbers.Add(faceNum++); - - for (int i = 0; i < this.faceNumbers.Count; i++) - if (this.faceNumbers[i] == -1) - this.faceNumbers[i] = faceNum++; - - this.numPrimFaces = faceNum; - } - } - public void MakeFaceUVs() - { - this.faceUVs = new List(); - foreach (Coord c in this.coords) - this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y))); - } public Profile Copy() { @@ -1047,24 +821,10 @@ namespace PrimMesher Profile copy = new Profile(); copy.coords.AddRange(this.coords); - copy.faceUVs.AddRange(this.faceUVs); if (needFaces) copy.faces.AddRange(this.faces); - if ((copy.calcVertexNormals = this.calcVertexNormals) == true) - { - copy.vertexNormals.AddRange(this.vertexNormals); - copy.faceNormal = this.faceNormal; - copy.cutNormal1 = this.cutNormal1; - copy.cutNormal2 = this.cutNormal2; - copy.us.AddRange(this.us); - copy.faceNumbers.AddRange(this.faceNumbers); - copy.cut1CoordIndices = new List(this.cut1CoordIndices); - copy.cut2CoordIndices = new List(this.cut2CoordIndices); - copy.hollowCoordIndices = new List(this.hollowCoordIndices); - copy.outerCoordIndices = new List(this.outerCoordIndices); - } copy.numOuterVerts = this.numOuterVerts; copy.numHollowVerts = this.numHollowVerts; @@ -1099,18 +859,6 @@ namespace PrimMesher for (i = 0; i < numVerts; i++) this.coords[i] *= q; - - if (this.calcVertexNormals) - { - int numNormals = this.vertexNormals.Count; - for (i = 0; i < numNormals; i++) - this.vertexNormals[i] *= q; - - this.faceNormal *= q; - this.cutNormal1 *= q; - this.cutNormal2 *= q; - - } } public void Scale(float x, float y) @@ -1146,29 +894,6 @@ namespace PrimMesher tmpFace.v1 = tmp; this.faces[i] = tmpFace; } - - if (this.calcVertexNormals) - { - int normalCount = this.vertexNormals.Count; - if (normalCount > 0) - { - Coord n = this.vertexNormals[normalCount - 1]; - n.Z = -n.Z; - this.vertexNormals[normalCount - 1] = n; - } - } - - this.faceNormal.X = -this.faceNormal.X; - this.faceNormal.Y = -this.faceNormal.Y; - this.faceNormal.Z = -this.faceNormal.Z; - - int numfaceUVs = this.faceUVs.Count; - for (i = 0; i < numfaceUVs; i++) - { - UVCoord uv = this.faceUVs[i]; - uv.V = 1.0f - uv.V; - this.faceUVs[i] = uv; - } } public void AddValue2FaceVertexIndices(int num) @@ -1186,25 +911,7 @@ namespace PrimMesher } } - public void AddValue2FaceNormalIndices(int num) - { - if (this.calcVertexNormals) - { - int numFaces = this.faces.Count; - Face tmpFace; - for (int i = 0; i < numFaces; i++) - { - tmpFace = this.faces[i]; - tmpFace.n1 += num; - tmpFace.n2 += num; - tmpFace.n3 += num; - - this.faces[i] = tmpFace; - } - } - } - - public void DumpRaw(String path, String name, String title) + public void DumpRaw(String path, String name, String title) { if (path == null) return; @@ -1451,11 +1158,9 @@ namespace PrimMesher private const float twoPi = 2.0f * (float)Math.PI; public List coords; - public List normals; +// public List normals; public List faces; - public List viewerFaces; - private int sides = 4; private int hollowSides = 4; private float profileStart = 0.0f; @@ -1478,15 +1183,8 @@ namespace PrimMesher public float revolutions = 1.0f; public int stepsPerRevolution = 24; - private int profileOuterFaceNumber = -1; - private int profileHollowFaceNumber = -1; - private bool hasProfileCut = false; private bool hasHollow = false; - public bool calcVertexNormals = false; - private bool normalsProcessed = false; - public bool viewerMode = false; - public bool sphereMode = false; public int numPrimFaces = 0; @@ -1518,27 +1216,16 @@ namespace PrimMesher s += "\nradius...............: " + this.radius.ToString(); s += "\nrevolutions..........: " + this.revolutions.ToString(); s += "\nstepsPerRevolution...: " + this.stepsPerRevolution.ToString(); - s += "\nsphereMode...........: " + this.sphereMode.ToString(); s += "\nhasProfileCut........: " + this.hasProfileCut.ToString(); - s += "\nhasHollow............: " + this.hasHollow.ToString(); - s += "\nviewerMode...........: " + this.viewerMode.ToString(); + s += "\nhasHollow............: " + this.hasHollow.ToString(); return s; } - public int ProfileOuterFaceNumber - { - get { return profileOuterFaceNumber; } - } - - public int ProfileHollowFaceNumber - { - get { return profileHollowFaceNumber; } - } - public bool HasProfileCut { get { return hasProfileCut; } + set { hasProfileCut = value; } } public bool HasHollow @@ -1555,6 +1242,7 @@ namespace PrimMesher /// /// /// + /// public PrimMesh(int sides, float profileStart, float profileEnd, float hollow, int hollowSides) { this.coords = new List(); @@ -1594,32 +1282,12 @@ namespace PrimMesher this.coords = new List(); this.faces = new List(); - if (this.viewerMode) - { - this.viewerFaces = new List(); - this.calcVertexNormals = true; - } - - if (this.calcVertexNormals) - this.normals = new List(); - int steps = 1; float length = this.pathCutEnd - this.pathCutBegin; - normalsProcessed = false; - if (this.viewerMode && this.sides == 3) - { - // prisms don't taper well so add some vertical resolution - // other prims may benefit from this but just do prisms for now - if (Math.Abs(this.taperX) > 0.01 || Math.Abs(this.taperY) > 0.01) - steps = (int)(steps * 4.5 * length); - } + this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f; - if (this.sphereMode) - this.hasProfileCut = this.profileEnd - this.profileStart < 0.4999f; - else - this.hasProfileCut = this.profileEnd - this.profileStart < 0.9999f; this.hasHollow = (this.hollow > 0.001f); float twistBegin = this.twistBegin / 360.0f * twoPi; @@ -1701,47 +1369,16 @@ namespace PrimMesher hollow *= 1.414f; } - Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, true, calcVertexNormals); + Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, this.hasProfileCut,true); this.errorMessage = profile.errorMessage; this.numPrimFaces = profile.numPrimFaces; - int cut1FaceNumber = profile.bottomFaceNumber + 1; - int cut2FaceNumber = cut1FaceNumber + 1; - if (!needEndFaces) - { - cut1FaceNumber -= 2; - cut2FaceNumber -= 2; - } - - profileOuterFaceNumber = profile.outerFaceNumber; - if (!needEndFaces) - profileOuterFaceNumber--; - - if (hasHollow) - { - profileHollowFaceNumber = profile.hollowFaceNumber; - if (!needEndFaces) - profileHollowFaceNumber--; - } - - int cut1Vert = -1; - int cut2Vert = -1; - if (hasProfileCut) - { - cut1Vert = hasHollow ? profile.coords.Count - 1 : 0; - cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts; - } - if (initialProfileRot != 0.0f) { profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); - if (viewerMode) - profile.MakeFaceUVs(); } - Coord lastCutNormal1 = new Coord(); - Coord lastCutNormal2 = new Coord(); float thisV = 0.0f; float lastV = 0.0f; @@ -1764,57 +1401,21 @@ namespace PrimMesher path.stepsPerRevolution = stepsPerRevolution; path.Create(pathType, steps); + + int lastNode = path.pathNodes.Count -1; for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) { PathNode node = path.pathNodes[nodeIndex]; Profile newLayer = profile.Copy(); - newLayer.Scale(node.xScale, node.yScale); + newLayer.Scale(node.xScale, node.yScale); newLayer.AddRot(node.rotation); newLayer.AddPos(node.position); if (needEndFaces && nodeIndex == 0) { newLayer.FlipNormals(); - - // add the bottom faces to the viewerFaces list - if (this.viewerMode) - { - Coord faceNormal = newLayer.faceNormal; - ViewerFace newViewerFace = new ViewerFace(profile.bottomFaceNumber); - int numFaces = newLayer.faces.Count; - List faces = newLayer.faces; - - for (int i = 0; i < numFaces; i++) - { - Face face = faces[i]; - newViewerFace.v1 = newLayer.coords[face.v1]; - newViewerFace.v2 = newLayer.coords[face.v2]; - newViewerFace.v3 = newLayer.coords[face.v3]; - - newViewerFace.coordIndex1 = face.v1; - newViewerFace.coordIndex2 = face.v2; - newViewerFace.coordIndex3 = face.v3; - - newViewerFace.n1 = faceNormal; - newViewerFace.n2 = faceNormal; - newViewerFace.n3 = faceNormal; - - newViewerFace.uv1 = newLayer.faceUVs[face.v1]; - newViewerFace.uv2 = newLayer.faceUVs[face.v2]; - newViewerFace.uv3 = newLayer.faceUVs[face.v3]; - - if (pathType == PathType.Linear) - { - newViewerFace.uv1.Flip(); - newViewerFace.uv2.Flip(); - newViewerFace.uv3.Flip(); - } - - this.viewerFaces.Add(newViewerFace); - } - } } // if (nodeIndex == 0) // append this layer @@ -1824,15 +1425,17 @@ namespace PrimMesher this.coords.AddRange(newLayer.coords); - if (this.calcVertexNormals) + if (needEndFaces) { - newLayer.AddValue2FaceNormalIndices(this.normals.Count); - this.normals.AddRange(newLayer.vertexNormals); + if (nodeIndex == 0) + this.faces.AddRange(newLayer.faces); + else if (nodeIndex == lastNode) + { + if (node.xScale > 1e-6 && node.yScale > 1e-6) + this.faces.AddRange(newLayer.faces); + } } - if (node.percentOfPath < this.pathCutBegin + 0.01f || node.percentOfPath > this.pathCutEnd - 0.01f) - this.faces.AddRange(newLayer.faces); - // fill faces between layers int numVerts = newLayer.coords.Count; @@ -1843,219 +1446,88 @@ namespace PrimMesher if (nodeIndex > 0) { - int startVert = coordsLen + 1; + int startVert = coordsLen; int endVert = this.coords.Count; - - if (sides < 5 || this.hasProfileCut || this.hasHollow) - startVert--; - - for (int i = startVert; i < endVert; i++) + if (!this.hasProfileCut) { - int iNext = i + 1; - if (i == endVert - 1) - iNext = startVert; + int i = startVert; + for (int l = 0; l < profile.numOuterVerts - 1; l++) + { + newFace1.v1 = i; + newFace1.v2 = i - numVerts; + newFace1.v3 = i + 1; + this.faces.Add(newFace1); - int whichVert = i - startVert; + newFace2.v1 = i + 1; + newFace2.v2 = i - numVerts; + newFace2.v3 = i + 1 - numVerts; + this.faces.Add(newFace2); + i++; + } newFace1.v1 = i; newFace1.v2 = i - numVerts; - newFace1.v3 = iNext; - - newFace1.n1 = newFace1.v1; - newFace1.n2 = newFace1.v2; - newFace1.n3 = newFace1.v3; + newFace1.v3 = startVert; this.faces.Add(newFace1); - newFace2.v1 = iNext; + newFace2.v1 = startVert; newFace2.v2 = i - numVerts; - newFace2.v3 = iNext - numVerts; - - newFace2.n1 = newFace2.v1; - newFace2.n2 = newFace2.v2; - newFace2.n3 = newFace2.v3; + newFace2.v3 = startVert - numVerts; this.faces.Add(newFace2); - if (this.viewerMode) + if (this.hasHollow) { - // add the side faces to the list of viewerFaces here - - int primFaceNum = profile.faceNumbers[whichVert]; - if (!needEndFaces) - primFaceNum -= 1; - - ViewerFace newViewerFace1 = new ViewerFace(primFaceNum); - ViewerFace newViewerFace2 = new ViewerFace(primFaceNum); - - int uIndex = whichVert; - if (!hasHollow && sides > 4 && uIndex < newLayer.us.Count - 1) + startVert = ++i; + for (int l = 0; l < profile.numHollowVerts - 1; l++) { - uIndex++; + newFace1.v1 = i; + newFace1.v2 = i - numVerts; + newFace1.v3 = i + 1; + this.faces.Add(newFace1); + + newFace2.v1 = i + 1; + newFace2.v2 = i - numVerts; + newFace2.v3 = i + 1 - numVerts; + this.faces.Add(newFace2); + i++; } - float u1 = newLayer.us[uIndex]; - float u2 = 1.0f; - if (uIndex < (int)newLayer.us.Count - 1) - u2 = newLayer.us[uIndex + 1]; - - if (whichVert == cut1Vert || whichVert == cut2Vert) - { - u1 = 0.0f; - u2 = 1.0f; - } - else if (sides < 5) - { - if (whichVert < profile.numOuterVerts) - { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled - // to reflect the entire texture width - u1 *= sides; - u2 *= sides; - u2 -= (int)u1; - u1 -= (int)u1; - if (u2 < 0.1f) - u2 = 1.0f; - } - } - - if (this.sphereMode) - { - if (whichVert != cut1Vert && whichVert != cut2Vert) - { - u1 = u1 * 2.0f - 1.0f; - u2 = u2 * 2.0f - 1.0f; - - if (whichVert >= newLayer.numOuterVerts) - { - u1 -= hollow; - u2 -= hollow; - } - - } - } - - newViewerFace1.uv1.U = u1; - newViewerFace1.uv2.U = u1; - newViewerFace1.uv3.U = u2; - - newViewerFace1.uv1.V = thisV; - newViewerFace1.uv2.V = lastV; - newViewerFace1.uv3.V = thisV; - - newViewerFace2.uv1.U = u2; - newViewerFace2.uv2.U = u1; - newViewerFace2.uv3.U = u2; - - newViewerFace2.uv1.V = thisV; - newViewerFace2.uv2.V = lastV; - newViewerFace2.uv3.V = lastV; - - newViewerFace1.v1 = this.coords[newFace1.v1]; - newViewerFace1.v2 = this.coords[newFace1.v2]; - newViewerFace1.v3 = this.coords[newFace1.v3]; - - newViewerFace2.v1 = this.coords[newFace2.v1]; - newViewerFace2.v2 = this.coords[newFace2.v2]; - newViewerFace2.v3 = this.coords[newFace2.v3]; - - newViewerFace1.coordIndex1 = newFace1.v1; - newViewerFace1.coordIndex2 = newFace1.v2; - newViewerFace1.coordIndex3 = newFace1.v3; - - newViewerFace2.coordIndex1 = newFace2.v1; - newViewerFace2.coordIndex2 = newFace2.v2; - newViewerFace2.coordIndex3 = newFace2.v3; - - // profile cut faces - if (whichVert == cut1Vert) - { - newViewerFace1.primFaceNumber = cut1FaceNumber; - newViewerFace2.primFaceNumber = cut1FaceNumber; - newViewerFace1.n1 = newLayer.cutNormal1; - newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1; - - newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1; - newViewerFace2.n2 = lastCutNormal1; - } - else if (whichVert == cut2Vert) - { - newViewerFace1.primFaceNumber = cut2FaceNumber; - newViewerFace2.primFaceNumber = cut2FaceNumber; - newViewerFace1.n1 = newLayer.cutNormal2; - newViewerFace1.n2 = lastCutNormal2; - newViewerFace1.n3 = lastCutNormal2; - - newViewerFace2.n1 = newLayer.cutNormal2; - newViewerFace2.n3 = newLayer.cutNormal2; - newViewerFace2.n2 = lastCutNormal2; - } - - else // outer and hollow faces - { - if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)) - { // looks terrible when path is twisted... need vertex normals here - newViewerFace1.CalcSurfaceNormal(); - newViewerFace2.CalcSurfaceNormal(); - } - else - { - newViewerFace1.n1 = this.normals[newFace1.n1]; - newViewerFace1.n2 = this.normals[newFace1.n2]; - newViewerFace1.n3 = this.normals[newFace1.n3]; - - newViewerFace2.n1 = this.normals[newFace2.n1]; - newViewerFace2.n2 = this.normals[newFace2.n2]; - newViewerFace2.n3 = this.normals[newFace2.n3]; - } - } - - this.viewerFaces.Add(newViewerFace1); - this.viewerFaces.Add(newViewerFace2); + newFace1.v1 = i; + newFace1.v2 = i - numVerts; + newFace1.v3 = startVert; + this.faces.Add(newFace1); + newFace2.v1 = startVert; + newFace2.v2 = i - numVerts; + newFace2.v3 = startVert - numVerts; + this.faces.Add(newFace2); } + + } - } - - lastCutNormal1 = newLayer.cutNormal1; - lastCutNormal2 = newLayer.cutNormal2; - lastV = thisV; - - if (needEndFaces && nodeIndex == path.pathNodes.Count - 1 && viewerMode) - { - // add the top faces to the viewerFaces list here - Coord faceNormal = newLayer.faceNormal; - ViewerFace newViewerFace = new ViewerFace(0); - int numFaces = newLayer.faces.Count; - List faces = newLayer.faces; - - for (int i = 0; i < numFaces; i++) + else { - Face face = faces[i]; - newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen]; - newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen]; - newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen]; - - newViewerFace.coordIndex1 = face.v1 - coordsLen; - newViewerFace.coordIndex2 = face.v2 - coordsLen; - newViewerFace.coordIndex3 = face.v3 - coordsLen; - - newViewerFace.n1 = faceNormal; - newViewerFace.n2 = faceNormal; - newViewerFace.n3 = faceNormal; - - newViewerFace.uv1 = newLayer.faceUVs[face.v1 - coordsLen]; - newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen]; - newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen]; - - if (pathType == PathType.Linear) + for (int i = startVert; i < endVert; i++) { - newViewerFace.uv1.Flip(); - newViewerFace.uv2.Flip(); - newViewerFace.uv3.Flip(); - } + int iNext = i + 1; + if (i == endVert - 1) + iNext = startVert; - this.viewerFaces.Add(newViewerFace); + newFace1.v1 = i; + newFace1.v2 = i - numVerts; + newFace1.v3 = iNext; + this.faces.Add(newFace1); + + newFace2.v1 = iNext; + newFace2.v2 = i - numVerts; + newFace2.v3 = iNext - numVerts; + this.faces.Add(newFace2); + + } } } + lastV = thisV; } // for (int nodeIndex = 0; nodeIndex < path.pathNodes.Count; nodeIndex++) @@ -2138,50 +1610,16 @@ namespace PrimMesher copy.radius = this.radius; copy.revolutions = this.revolutions; copy.stepsPerRevolution = this.stepsPerRevolution; - copy.calcVertexNormals = this.calcVertexNormals; - copy.normalsProcessed = this.normalsProcessed; - copy.viewerMode = this.viewerMode; + copy.numPrimFaces = this.numPrimFaces; copy.errorMessage = this.errorMessage; copy.coords = new List(this.coords); copy.faces = new List(this.faces); - copy.viewerFaces = new List(this.viewerFaces); - copy.normals = new List(this.normals); return copy; } - /// - /// Calculate surface normals for all of the faces in the list of faces in this mesh - /// - public void CalcNormals() - { - if (normalsProcessed) - return; - - normalsProcessed = true; - - int numFaces = faces.Count; - - if (!this.calcVertexNormals) - this.normals = new List(); - - for (int i = 0; i < numFaces; i++) - { - Face face = faces[i]; - - this.normals.Add(SurfaceNormal(i).Normalize()); - - int normIndex = normals.Count - 1; - face.n1 = normIndex; - face.n2 = normIndex; - face.n3 = normIndex; - - this.faces[i] = face; - } - } - /// /// Adds a value to each XYZ vertex coordinate in the mesh /// @@ -2202,18 +1640,6 @@ namespace PrimMesher vert.Z += z; this.coords[i] = vert; } - - if (this.viewerFaces != null) - { - int numViewerFaces = this.viewerFaces.Count; - - for (i = 0; i < numViewerFaces; i++) - { - ViewerFace v = this.viewerFaces[i]; - v.AddPos(x, y, z); - this.viewerFaces[i] = v; - } - } } /// @@ -2227,38 +1653,11 @@ namespace PrimMesher for (i = 0; i < numVerts; i++) this.coords[i] *= q; - - if (this.normals != null) - { - int numNormals = this.normals.Count; - for (i = 0; i < numNormals; i++) - this.normals[i] *= q; - } - - if (this.viewerFaces != null) - { - int numViewerFaces = this.viewerFaces.Count; - - for (i = 0; i < numViewerFaces; i++) - { - ViewerFace v = this.viewerFaces[i]; - v.v1 *= q; - v.v2 *= q; - v.v3 *= q; - - v.n1 *= q; - v.n2 *= q; - v.n3 *= q; - this.viewerFaces[i] = v; - } - } } #if VERTEX_INDEXER public VertexIndexer GetVertexIndexer() { - if (this.viewerMode && this.viewerFaces.Count > 0) - return new VertexIndexer(this); return null; } #endif @@ -2278,21 +1677,6 @@ namespace PrimMesher Coord m = new Coord(x, y, z); for (i = 0; i < numVerts; i++) this.coords[i] *= m; - - if (this.viewerFaces != null) - { - int numViewerFaces = this.viewerFaces.Count; - for (i = 0; i < numViewerFaces; i++) - { - ViewerFace v = this.viewerFaces[i]; - v.v1 *= m; - v.v2 *= m; - v.v3 *= m; - this.viewerFaces[i] = v; - } - - } - } /// diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs index 0df71eb95f..5030cec783 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEMeshWorker.cs @@ -448,7 +448,7 @@ namespace OpenSim.Region.Physics.OdePlugin else { repData.meshState = MeshState.needMesh; - mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, false, convex, true); + mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex, true); if (mesh == null) { repData.meshState = MeshState.MeshFailed; @@ -513,7 +513,7 @@ namespace OpenSim.Region.Physics.OdePlugin clod = (int)LevelOfDetail.Low; } - mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, false, convex, true); + mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex, true); if (mesh == null) { @@ -929,4 +929,4 @@ namespace OpenSim.Region.Physics.OdePlugin repData.actor.Name); } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index faa948809f..7cabddd18f 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs @@ -25,7 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* Revision 2011/12 by Ubit Umarov +/* Revision 2011/12/13 by Ubit Umarov * * */ @@ -1736,7 +1736,9 @@ namespace OpenSim.Region.Physics.OdePlugin d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableSteps(Body, body_autodisable_frames); - d.BodySetDamping(Body, .005f, .005f); + d.BodySetAutoDisableAngularThreshold(Body, 0.01f); + d.BodySetAutoDisableLinearThreshold(Body, 0.01f); + d.BodySetDamping(Body, .005f, .001f); if (m_targetSpace != IntPtr.Zero) { @@ -2144,7 +2146,7 @@ namespace OpenSim.Region.Physics.OdePlugin _mass = primMass; // just in case - d.MassSetBoxTotal(out primdMass, primMass, m_OBB.X, m_OBB.Y, m_OBB.Z); + d.MassSetBoxTotal(out primdMass, primMass, 2.0f * m_OBB.X, 2.0f * m_OBB.Y, 2.0f * m_OBB.Z); d.MassTranslate(ref primdMass, m_OBBOffset.X, @@ -2362,6 +2364,7 @@ namespace OpenSim.Region.Physics.OdePlugin MakeBody(); } + #region changes private void changeadd() @@ -3213,7 +3216,6 @@ namespace OpenSim.Region.Physics.OdePlugin if (++bodydisablecontrol < 20) return; - d.BodyEnable(Body); } @@ -3381,11 +3383,12 @@ namespace OpenSim.Region.Physics.OdePlugin } } - public void UpdatePositionAndVelocity() + public void UpdatePositionAndVelocity(int frame) { if (_parent == null && !m_disabled && !m_building && !m_outbounds && Body != IntPtr.Zero) { - if (d.BodyIsEnabled(Body) || !_zeroFlag) + bool bodyenabled = d.BodyIsEnabled(Body); + if (bodyenabled || !_zeroFlag) { bool lastZeroFlag = _zeroFlag; @@ -3478,13 +3481,13 @@ namespace OpenSim.Region.Physics.OdePlugin // tolerance values depende a lot on simulation noise... // use simple math.abs since we dont need to be exact - if ( - (Math.Abs(_position.X - lpos.X) < 0.001f) - && (Math.Abs(_position.Y - lpos.Y) < 0.001f) - && (Math.Abs(_position.Z - lpos.Z) < 0.001f) - && (Math.Abs(_orientation.X - ori.X) < 0.0001f) - && (Math.Abs(_orientation.Y - ori.Y) < 0.0001f) - && (Math.Abs(_orientation.Z - ori.Z) < 0.0001f) // ignore W + if (!bodyenabled || + (Math.Abs(_position.X - lpos.X) < 0.005f) + && (Math.Abs(_position.Y - lpos.Y) < 0.005f) + && (Math.Abs(_position.Z - lpos.Z) < 0.005f) + && (Math.Abs(_orientation.X - ori.X) < 0.001f) + && (Math.Abs(_orientation.Y - ori.Y) < 0.001f) + && (Math.Abs(_orientation.Z - ori.Z) < 0.001f) // ignore W ) { _zeroFlag = true; @@ -3499,9 +3502,9 @@ namespace OpenSim.Region.Physics.OdePlugin _acceleration = _velocity; - if ((Math.Abs(vel.X) < 0.001f) && - (Math.Abs(vel.Y) < 0.001f) && - (Math.Abs(vel.Z) < 0.001f)) + if ((Math.Abs(vel.X) < 0.005f) && + (Math.Abs(vel.Y) < 0.005f) && + (Math.Abs(vel.Z) < 0.005f)) { _velocity = Vector3.Zero; float t = -m_invTimeStep; @@ -3538,6 +3541,15 @@ namespace OpenSim.Region.Physics.OdePlugin } } + _position.X = lpos.X; + _position.Y = lpos.Y; + _position.Z = lpos.Z; + + _orientation.X = ori.X; + _orientation.Y = ori.Y; + _orientation.Z = ori.Z; + _orientation.W = ori.W; + if (_zeroFlag) { if (lastZeroFlag) @@ -3556,14 +3568,6 @@ namespace OpenSim.Region.Physics.OdePlugin return; } - _position.X = lpos.X; - _position.Y = lpos.Y; - _position.Z = lpos.Z; - - _orientation.X = ori.X; - _orientation.Y = ori.Y; - _orientation.Z = ori.Z; - _orientation.W = ori.W; base.RequestPhysicsterseUpdate(); m_lastUpdateSent = false; } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs index 2923ccfd38..73ababac21 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODERayCastRequestManager.cs @@ -680,4 +680,4 @@ namespace OpenSim.Region.Physics.OdePlugin public RayFilterFlags filter; public Quaternion orientation; } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs index 10d7d50d95..1f09dc76e2 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs @@ -1869,7 +1869,7 @@ namespace OdeAPI [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetCleanup"), SuppressUnmanagedCodeSecurity] public static extern void SpaceSetCleanup(IntPtr space, bool mode); - [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetSublevel"), SuppressUnmanagedCodeSecurity] + [DllImport("ode.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetSublevel"), SuppressUnmanagedCodeSecurity] public static extern void SpaceSetSublevel(IntPtr space, int sublevel); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSweepAndPruneSpaceCreate"), SuppressUnmanagedCodeSecurity] diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 754bc86978..49dc03ce1a 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +// Revision 2011/12/13 by Ubit Umarov //#define SPAM using System; @@ -43,25 +44,7 @@ using OpenMetaverse; namespace OpenSim.Region.Physics.OdePlugin { - public enum StatusIndicators : int - { - Generic = 0, - Start = 1, - End = 2 - } - - public struct sCollisionData - { - public uint ColliderLocalId; - public uint CollidedWithLocalId; - public int NumberOfCollisions; - public int CollisionType; - public int StatusIndicator; - public int lastframe; - } - - - // colision flags of things others can colide with + // colision flags of things others can colide with // rays, sensors, probes removed since can't be colided with // The top space where things are placed provided further selection // ie physical are in active space nonphysical in static @@ -188,12 +171,14 @@ namespace OpenSim.Region.Physics.OdePlugin public bool OdeUbitLib = false; // private int threadid = 0; - private Random fluidRandomizer = new Random(Environment.TickCount); +// private Random fluidRandomizer = new Random(Environment.TickCount); - const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; - const float MaxERP = 0.8f; - const float minERP = 0.1f; +// const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; + + const d.ContactFlags comumContactFlags = d.ContactFlags.Bounce | d.ContactFlags.Approx1; + const float comumContactERP = 0.7f; const float comumContactCFM = 0.0001f; + const float comumContactSLIP = 0.000001f; float frictionMovementMult = 0.8f; @@ -236,8 +221,8 @@ namespace OpenSim.Region.Physics.OdePlugin public float geomDefaultDensity = 10.000006836f; - public int geomContactPointsStartthrottle = 3; - public int geomUpdatesPerThrottledUpdate = 15; +// public int geomContactPointsStartthrottle = 3; +// public int geomUpdatesPerThrottledUpdate = 15; public float bodyPIDD = 35f; public float bodyPIDG = 25; @@ -246,7 +231,6 @@ namespace OpenSim.Region.Physics.OdePlugin public int bodyFramesAutoDisable = 5; - private d.NearCallback nearCallback; private HashSet _characters = new HashSet(); @@ -266,11 +250,12 @@ namespace OpenSim.Region.Physics.OdePlugin // public Dictionary geom_name_map = new Dictionary(); public Dictionary actor_name_map = new Dictionary(); - private float contactsurfacelayer = 0.002f; + private float contactsurfacelayer = 0.001f; private int contactsPerCollision = 80; internal IntPtr ContactgeomsArray = IntPtr.Zero; private IntPtr GlobalContactsArray = IntPtr.Zero; + private d.Contact SharedTmpcontact = new d.Contact(); const int maxContactsbeforedeath = 4000; private volatile int m_global_contactcount = 0; @@ -283,7 +268,7 @@ namespace OpenSim.Region.Physics.OdePlugin private Dictionary TerrainHeightFieldHeights = new Dictionary(); private Dictionary TerrainHeightFieldHeightsHandlers = new Dictionary(); - private int m_physicsiterations = 10; + private int m_physicsiterations = 15; private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag // private PhysicsActor PANull = new NullPhysicsActor(); private float step_time = 0.0f; @@ -303,8 +288,6 @@ namespace OpenSim.Region.Physics.OdePlugin public IntPtr StaticSpace; // space for the static things around public IntPtr GroundSpace; // space for ground - public IntPtr SharedRay; - // some speedup variables private int spaceGridMaxX; private int spaceGridMaxY; @@ -431,8 +414,6 @@ namespace OpenSim.Region.Physics.OdePlugin contactgroup = d.JointGroupCreate(0); //contactgroup - SharedRay = d.CreateRay(TopSpace, 1.0f); - d.WorldSetAutoDisableFlag(world, false); } } @@ -481,10 +462,10 @@ namespace OpenSim.Region.Physics.OdePlugin metersInSpace = physicsconfig.GetFloat("meters_in_small_space", metersInSpace); - contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer); +// contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer); ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE); - m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", m_physicsiterations); +// m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", m_physicsiterations); avDensity = physicsconfig.GetFloat("av_density", avDensity); avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk); @@ -492,8 +473,8 @@ namespace OpenSim.Region.Physics.OdePlugin contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision); - geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3); - geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); +// geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3); +// geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); // geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5); geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity); @@ -508,6 +489,23 @@ namespace OpenSim.Region.Physics.OdePlugin } } + + d.WorldSetCFM(world, comumContactCFM); + d.WorldSetERP(world, comumContactERP); + + d.WorldSetGravity(world, gravityx, gravityy, gravityz); + + d.WorldSetLinearDamping(world, 0.002f); + d.WorldSetAngularDamping(world, 0.002f); + d.WorldSetAngularDampingThreshold(world, 0f); + d.WorldSetLinearDampingThreshold(world, 0f); + d.WorldSetMaxAngularSpeed(world, 100f); + + d.WorldSetQuickStepNumIterations(world, m_physicsiterations); + + d.WorldSetContactSurfaceLayer(world, contactsurfacelayer); + d.WorldSetContactMaxCorrectingVel(world, 60.0f); + m_meshWorker = new ODEMeshWorker(this, m_log, meshmerizer, physicsconfig); HalfOdeStep = ODE_STEPSIZE * 0.5f; @@ -516,6 +514,20 @@ namespace OpenSim.Region.Physics.OdePlugin ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.unmanagedSizeOf); + SharedTmpcontact.geom.g1 = IntPtr.Zero; + SharedTmpcontact.geom.g2 = IntPtr.Zero; + + SharedTmpcontact.geom.side1 = -1; + SharedTmpcontact.geom.side2 = -1; + + SharedTmpcontact.surface.mode = comumContactFlags; + SharedTmpcontact.surface.mu = 0; + SharedTmpcontact.surface.bounce = 0; + SharedTmpcontact.surface.soft_cfm = comumContactCFM; + SharedTmpcontact.surface.soft_erp = comumContactERP; + SharedTmpcontact.surface.slip1 = comumContactSLIP; + SharedTmpcontact.surface.slip2 = comumContactSLIP; + m_materialContactsData[(int)Material.Stone].mu = 0.8f; m_materialContactsData[(int)Material.Stone].bounce = 0.4f; @@ -540,27 +552,6 @@ namespace OpenSim.Region.Physics.OdePlugin m_materialContactsData[(int)Material.light].mu = 0.0f; m_materialContactsData[(int)Material.light].bounce = 0.0f; - // Set the gravity,, don't disable things automatically (we set it explicitly on some things) - - d.WorldSetGravity(world, gravityx, gravityy, gravityz); - d.WorldSetContactSurfaceLayer(world, contactsurfacelayer); - - d.WorldSetLinearDamping(world, 0.002f); - d.WorldSetAngularDamping(world, 0.002f); - d.WorldSetAngularDampingThreshold(world, 0f); - d.WorldSetLinearDampingThreshold(world, 0f); - d.WorldSetMaxAngularSpeed(world, 100f); - - d.WorldSetCFM(world,1e-6f); // a bit harder than default - //d.WorldSetCFM(world, 1e-4f); // a bit harder than default - d.WorldSetERP(world, 0.6f); // higher than original - - // Set how many steps we go without running collision testing - // This is in addition to the step size. - // Essentially Steps * m_physicsiterations - d.WorldSetQuickStepNumIterations(world, m_physicsiterations); - - d.WorldSetContactMaxCorrectingVel(world, 60.0f); spacesPerMeter = 1 / metersInSpace; spaceGridMaxX = (int)(WorldExtents.X * spacesPerMeter); @@ -631,40 +622,21 @@ namespace OpenSim.Region.Physics.OdePlugin // sets a global contact for a joint for contactgeom , and base contact description) - private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom, float mu, float bounce, float cfm, float erpscale, float dscale) + + + private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom) { - if (GlobalContactsArray == IntPtr.Zero || m_global_contactcount >= maxContactsbeforedeath) + if (m_global_contactcount >= maxContactsbeforedeath) return IntPtr.Zero; - float erp = contactGeom.depth; - erp *= erpscale; - if (erp < minERP) - erp = minERP; - else if (erp > MaxERP) - erp = MaxERP; + m_global_contactcount++; - float depth = contactGeom.depth * dscale; - if (depth > 0.5f) - depth = 0.5f; - - d.Contact newcontact = new d.Contact(); - newcontact.geom.depth = depth; - newcontact.geom.g1 = contactGeom.g1; - newcontact.geom.g2 = contactGeom.g2; - newcontact.geom.pos = contactGeom.pos; - newcontact.geom.normal = contactGeom.normal; - newcontact.geom.side1 = contactGeom.side1; - newcontact.geom.side2 = contactGeom.side2; - - // this needs bounce also - newcontact.surface.mode = comumContactFlags; - newcontact.surface.mu = mu; - newcontact.surface.bounce = bounce; - newcontact.surface.soft_cfm = cfm; - newcontact.surface.soft_erp = erp; + SharedTmpcontact.geom.depth = contactGeom.depth; + SharedTmpcontact.geom.pos = contactGeom.pos; + SharedTmpcontact.geom.normal = contactGeom.normal; IntPtr contact = new IntPtr(GlobalContactsArray.ToInt64() + (Int64)(m_global_contactcount * d.Contact.unmanagedSizeOf)); - Marshal.StructureToPtr(newcontact, contact, true); + Marshal.StructureToPtr(SharedTmpcontact, contact, true); return d.JointCreateContactPtr(world, contactgroup, contact); } @@ -825,10 +797,12 @@ namespace OpenSim.Region.Physics.OdePlugin if (!GetCurContactGeom(0, ref curContact)) return; + ContactPoint maxDepthContact = new ContactPoint(); + // do volume detection case if ((p1.IsVolumeDtc || p2.IsVolumeDtc)) { - ContactPoint maxDepthContact = new ContactPoint( + maxDepthContact = new ContactPoint( new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z), new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z), curContact.depth, false @@ -842,10 +816,7 @@ namespace OpenSim.Region.Physics.OdePlugin float mu = 0; float bounce = 0; - float cfm = 0.0001f; - float erpscale = 1.0f; - float dscale = 1.0f; - bool IgnoreNegSides = false; +// bool IgnoreNegSides = false; ContactData contactdata1 = new ContactData(0, 0, false); ContactData contactdata2 = new ContactData(0, 0, false); @@ -890,7 +861,9 @@ namespace OpenSim.Region.Physics.OdePlugin break; case (int)ActorTypes.Prim: - if ((p1.Velocity - p2.Velocity).LengthSquared() > 0.0f) + Vector3 relV = p1.Velocity - p2.Velocity; + float relVlenSQ = relV.LengthSquared(); + if (relVlenSQ > 0.0001f) { p1.CollidingObj = true; p2.CollidingObj = true; @@ -900,21 +873,7 @@ namespace OpenSim.Region.Physics.OdePlugin bounce = contactdata1.bounce * contactdata2.bounce; mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); - cfm = p1.Mass; - if (cfm > p2.Mass) - cfm = p2.Mass; - dscale = 10 / cfm; - dscale = (float)Math.Sqrt(dscale); - if (dscale > 1.0f) - dscale = 1.0f; - erpscale = cfm * 0.01f; - cfm = 0.0001f / cfm; - if (cfm > 0.01f) - cfm = 0.01f; - else if (cfm < 0.00001f) - cfm = 0.00001f; - - if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) + if (relVlenSQ > 0.01f) mu *= frictionMovementMult; break; @@ -923,27 +882,17 @@ namespace OpenSim.Region.Physics.OdePlugin p1.getContactData(ref contactdata1); bounce = contactdata1.bounce * TerrainBounce; mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); + if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f) mu *= frictionMovementMult; p1.CollidingGround = true; - - cfm = p1.Mass; - dscale = 10 / cfm; - dscale = (float)Math.Sqrt(dscale); - if (dscale > 1.0f) - dscale = 1.0f; - erpscale = cfm * 0.01f; - cfm = 0.0001f / cfm; - if (cfm > 0.01f) - cfm = 0.01f; - else if (cfm < 0.00001f) - cfm = 0.00001f; - +/* if (d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass) { if (curContact.side1 > 0) IgnoreNegSides = true; } + */ break; case (int)ActorTypes.Water: @@ -961,22 +910,8 @@ namespace OpenSim.Region.Physics.OdePlugin bounce = contactdata2.bounce * TerrainBounce; mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction); - cfm = p2.Mass; - dscale = 10 / cfm; - dscale = (float)Math.Sqrt(dscale); - - if (dscale > 1.0f) - dscale = 1.0f; - - erpscale = cfm * 0.01f; - cfm = 0.0001f / cfm; - if (cfm > 0.01f) - cfm = 0.01f; - else if (cfm < 0.00001f) - cfm = 0.00001f; - - if (curContact.side1 > 0) // should be 2 ? - IgnoreNegSides = true; +// if (curContact.side1 > 0) // should be 2 ? +// IgnoreNegSides = true; if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f) mu *= frictionMovementMult; @@ -993,26 +928,24 @@ namespace OpenSim.Region.Physics.OdePlugin if (ignore) return; - - d.ContactGeom maxContact = curContact; - // if (IgnoreNegSides && curContact.side1 < 0) - // maxContact.depth = float.MinValue; - - d.ContactGeom minContact = curContact; - // if (IgnoreNegSides && curContact.side1 < 0) - // minContact.depth = float.MaxValue; - IntPtr Joint; bool FeetCollision = false; int ncontacts = 0; - int i = 0; + maxDepthContact = new ContactPoint(); + maxDepthContact.PenetrationDepth = float.MinValue; + ContactPoint minDepthContact = new ContactPoint(); + minDepthContact.PenetrationDepth = float.MaxValue; + + SharedTmpcontact.geom.depth = 0; + SharedTmpcontact.surface.mu = mu; + SharedTmpcontact.surface.bounce = bounce; + while (true) { - -// if (!(IgnoreNegSides && curContact.side1 < 0)) +// if (!(IgnoreNegSides && curContact.side1 < 0)) { bool noskip = true; if (dop1ava) @@ -1029,26 +962,32 @@ namespace OpenSim.Region.Physics.OdePlugin if (noskip) { - m_global_contactcount++; - if (m_global_contactcount >= maxContactsbeforedeath) - break; - - ncontacts++; - - Joint = CreateContacJoint(ref curContact, mu, bounce, cfm, erpscale, dscale); + Joint = CreateContacJoint(ref curContact); if (Joint == IntPtr.Zero) break; d.JointAttach(Joint, b1, b2); - if (curContact.depth > maxContact.depth) - maxContact = curContact; + ncontacts++; - if (curContact.depth < minContact.depth) - minContact = curContact; + if (curContact.depth > maxDepthContact.PenetrationDepth) + { + maxDepthContact.Position.X = curContact.pos.X; + maxDepthContact.Position.Y = curContact.pos.Y; + maxDepthContact.Position.Z = curContact.pos.Z; + maxDepthContact.PenetrationDepth = curContact.depth; + maxDepthContact.CharacterFeet = FeetCollision; + } + + if (curContact.depth < minDepthContact.PenetrationDepth) + { + minDepthContact.PenetrationDepth = curContact.depth; + minDepthContact.SurfaceNormal.X = curContact.normal.X; + minDepthContact.SurfaceNormal.Y = curContact.normal.Y; + minDepthContact.SurfaceNormal.Z = curContact.normal.Z; + } } } - if (++i >= count) break; @@ -1058,11 +997,10 @@ namespace OpenSim.Region.Physics.OdePlugin if (ncontacts > 0) { - ContactPoint maxDepthContact = new ContactPoint( - new Vector3(maxContact.pos.X, maxContact.pos.Y, maxContact.pos.Z), - new Vector3(minContact.normal.X, minContact.normal.Y, minContact.normal.Z), - maxContact.depth, FeetCollision - ); + maxDepthContact.SurfaceNormal.X = minDepthContact.SurfaceNormal.X; + maxDepthContact.SurfaceNormal.Y = minDepthContact.SurfaceNormal.Y; + maxDepthContact.SurfaceNormal.Z = minDepthContact.SurfaceNormal.Z; + collision_accounting_events(p1, p2, maxDepthContact); } } @@ -1629,16 +1567,15 @@ namespace OpenSim.Region.Physics.OdePlugin if (framecount < 0) framecount = 0; - framecount++; - int curphysiteractions; +// int curphysiteractions; // if in trouble reduce step resolution - if (step_time >= m_SkipFramesAtms) - curphysiteractions = m_physicsiterations / 2; - else - curphysiteractions = m_physicsiterations; +// if (step_time >= m_SkipFramesAtms) +// curphysiteractions = m_physicsiterations / 2; +// else +// curphysiteractions = m_physicsiterations; // checkThread(); int nodeframes = 0; @@ -1653,14 +1590,12 @@ namespace OpenSim.Region.Physics.OdePlugin } ODEchangeitem item; - - - d.WorldSetQuickStepNumIterations(world, curphysiteractions); +// d.WorldSetQuickStepNumIterations(world, curphysiteractions); int loopstartMS = Util.EnvironmentTickCount(); int looptimeMS = 0; - + while (step_time > HalfOdeStep) { @@ -1763,6 +1698,7 @@ namespace OpenSim.Region.Physics.OdePlugin // do a ode simulation step d.WorldQuickStep(world, ODE_STEPSIZE); +// d.WorldStep(world, ODE_STEPSIZE); d.JointGroupEmpty(contactgroup); // update managed ideia of physical data and do updates to core @@ -1789,7 +1725,7 @@ namespace OpenSim.Region.Physics.OdePlugin { if (actor.IsPhysical) { - actor.UpdatePositionAndVelocity(); + actor.UpdatePositionAndVelocity(framecount); } } }