From 4e72cf9ee21dd8833af860fa5af4fc91e11018cb Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 29 May 2013 02:08:14 +0100 Subject: [PATCH 01/14] *** DANGER TESTING **** changed prims mesh generation hopefully removing spurius faces. CHanged several aspects. Fixed prims inertia that was too low, still using box as model. Increased number of quickstep SOR iterations to 15. Keep it 15 even on heavy load ( will only jump simulation time). --- .../Region/Physics/UbitMeshing/HelperTypes.cs | 4 +- OpenSim/Region/Physics/UbitMeshing/Mesh.cs | 33 +- .../Region/Physics/UbitMeshing/Meshmerizer.cs | 64 +- .../Region/Physics/UbitMeshing/PrimMesher.cs | 1246 +++++------------ .../Physics/UbitOdePlugin/ODEMeshWorker.cs | 6 +- .../Region/Physics/UbitOdePlugin/ODEPrim.cs | 52 +- .../UbitOdePlugin/ODERayCastRequestManager.cs | 2 +- .../Region/Physics/UbitOdePlugin/OdeApi.cs | 2 +- .../Region/Physics/UbitOdePlugin/OdeScene.cs | 286 ++-- 9 files changed, 510 insertions(+), 1185 deletions(-) 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); } } } From f00ecf5fe71df4eb5ad5dd1c195616300e988820 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 29 May 2013 02:18:05 +0100 Subject: [PATCH 02/14] missing files --- OpenSim/Region/Physics/Manager/IMesher.cs | 1 + OpenSim/Region/Physics/Manager/ZeroMesher.cs | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs index 5485eb77a1..e290dc918f 100644 --- a/OpenSim/Region/Physics/Manager/IMesher.cs +++ b/OpenSim/Region/Physics/Manager/IMesher.cs @@ -37,6 +37,7 @@ namespace OpenSim.Region.Physics.Manager { IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod); IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical); + IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex, bool forOde); IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache, bool convex, bool forOde); IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex); void ReleaseMesh(IMesh mesh); diff --git a/OpenSim/Region/Physics/Manager/ZeroMesher.cs b/OpenSim/Region/Physics/Manager/ZeroMesher.cs index 80ecf664f6..890951ffba 100644 --- a/OpenSim/Region/Physics/Manager/ZeroMesher.cs +++ b/OpenSim/Region/Physics/Manager/ZeroMesher.cs @@ -64,20 +64,20 @@ namespace OpenSim.Region.Physics.Manager { public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) { - return CreateMesh(primName, primShape, size, lod, false, false); + return CreateMesh(primName, primShape, size, lod, false); } - 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 shouldCache, bool convex, bool forOde) + { + return CreateMesh(primName, primShape, size, lod, false); + } + + public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex,bool forOde) { return CreateMesh(primName, primShape, size, lod, false); } public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) - { - return CreateMesh(primName, primShape, size, lod, false, false); - } - - public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) { // Remove the reference to the encoded JPEG2000 data so it can be GCed primShape.SculptData = OpenMetaverse.Utils.EmptyBytes; From 088284677019b959c2d140eedbd4e5d3baabe380 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 29 May 2013 02:21:02 +0100 Subject: [PATCH 03/14] missing file --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index d181b78a01..a32f401bc8 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -715,6 +715,11 @@ namespace OpenSim.Region.Physics.Meshing return CreateMesh(primName, primShape, size, lod, isPhysical, true); } + public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex, bool forOde) + { + return CreateMesh(primName, primShape, size, lod, isPhysical, true); + } + public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool shouldCache) { #if SPAM From 1cf24b70925f206f334fadb0baf20779aa9793f6 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 29 May 2013 04:47:59 +0100 Subject: [PATCH 04/14] make sure friction slip parameters are zero ( or other value ) and not default cmf --- OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 49dc03ce1a..8abf6cf73d 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -175,10 +175,10 @@ namespace OpenSim.Region.Physics.OdePlugin // 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 d.ContactFlags comumContactFlags = d.ContactFlags.Bounce | d.ContactFlags.Approx1 | d.ContactFlags.Slip1 | d.ContactFlags.Slip2; const float comumContactERP = 0.7f; const float comumContactCFM = 0.0001f; - const float comumContactSLIP = 0.000001f; + const float comumContactSLIP = 0f; float frictionMovementMult = 0.8f; @@ -411,7 +411,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomSetCategoryBits(GroundSpace, (uint)(CollisionCategories.Land)); d.GeomSetCollideBits(GroundSpace, 0); - contactgroup = d.JointGroupCreate(0); + contactgroup = d.JointGroupCreate(maxContactsbeforedeath + 1); //contactgroup d.WorldSetAutoDisableFlag(world, false); From 269febc87e1aba24fff09e9fb0d77eee0a73b185 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 29 May 2013 06:32:26 +0100 Subject: [PATCH 05/14] let gravity modifier, friction, restitution and density changes be applied to prim. Only have efect on root prim. Density doesn't get effect imediatly, only on next change of size or shape. density change implies a full body rebuild to be done later, after reducing the number of sets sop does. Other parameters should work. **** mainly untested *** --- .../Physics/UbitOdePlugin/ODEDynamics.cs | 19 +++++-- .../Region/Physics/UbitOdePlugin/ODEPrim.cs | 52 ++++++++++++++++++- 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs index a7dda7acd2..3c952ae7fe 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs @@ -137,6 +137,7 @@ namespace OpenSim.Region.Physics.OdePlugin float m_amdampY; float m_amdampZ; + float m_gravmod; public float FrictionFactor { @@ -146,6 +147,14 @@ namespace OpenSim.Region.Physics.OdePlugin } } + public float GravMod + { + set + { + m_gravmod = value; + } + } + public ODEDynamics(OdePrim rootp) { @@ -153,6 +162,7 @@ namespace OpenSim.Region.Physics.OdePlugin _pParentScene = rootPrim._parent_scene; m_timestep = _pParentScene.ODE_STEPSIZE; m_invtimestep = 1.0f / m_timestep; + m_gravmod = rootPrim.GravModifier; } public void DoSetVehicle(VehicleData vd) @@ -816,7 +826,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_lmEfect = 0; m_ffactor = 1f; } - + // hover if (m_VhoverTimescale < 300 && rootPrim.prim_geom != IntPtr.Zero) { @@ -862,7 +872,7 @@ namespace OpenSim.Region.Physics.OdePlugin force.Z += perr; ldampZ *= -curVel.Z; - force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy); + force.Z += _pParentScene.gravityz * m_gravmod * (1f - m_VehicleBuoyancy); } else // no buoyancy force.Z += _pParentScene.gravityz; @@ -870,7 +880,7 @@ namespace OpenSim.Region.Physics.OdePlugin else { // default gravity and Buoyancy - force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy); + force.Z += _pParentScene.gravityz * m_gravmod * (1f - m_VehicleBuoyancy); } // linear deflection @@ -1063,8 +1073,7 @@ namespace OpenSim.Region.Physics.OdePlugin torque.Y -= curLocalAngVel.Y * m_amdampY; torque.Z -= curLocalAngVel.Z * m_amdampZ; } - - + if (force.X != 0 || force.Y != 0 || force.Z != 0) { diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index 7cabddd18f..e3f88c688e 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs @@ -115,6 +115,7 @@ namespace OpenSim.Region.Physics.OdePlugin private int body_autodisable_frames; public int bodydisablecontrol; + private float m_gravmod = 1.0f; // Default we're a Geometry @@ -914,6 +915,55 @@ namespace OpenSim.Region.Physics.OdePlugin bounce = _parent_scene.m_materialContactsData[pMaterial].bounce; } + public override float Density + { + get + { + return m_density * 100f; + } + set + { + m_density = value / 100f; + // for not prim mass is not updated since this implies full rebuild of body inertia TODO + } + } + public override float GravModifier + { + get + { + return m_gravmod; + } + set + { + m_gravmod = value; + if (m_vehicle != null) + m_vehicle.GravMod = m_gravmod; + } + } + public override float Friction + { + get + { + return mu; + } + set + { + mu = value; + } + } + + public override float Restitution + { + get + { + return bounce; + } + set + { + bounce = value; + } + } + public void setPrimForRemoval() { AddChange(changes.Remove, null); @@ -3336,7 +3386,7 @@ namespace OpenSim.Region.Physics.OdePlugin } else { - float b = (1.0f - m_buoyancy); + float b = (1.0f - m_buoyancy) * m_gravmod; fx = _parent_scene.gravityx * b; fy = _parent_scene.gravityy * b; fz = _parent_scene.gravityz * b; From d5b1baffece161a21248f9fa84164cfcdd2fd813 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 29 May 2013 06:45:25 +0100 Subject: [PATCH 06/14] correction to previus comment: all parameters but gravity modifier have efect on all prims. --- OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index e3f88c688e..c247e6807f 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs @@ -117,7 +117,6 @@ namespace OpenSim.Region.Physics.OdePlugin public int bodydisablecontrol; private float m_gravmod = 1.0f; - // Default we're a Geometry private CollisionCategories m_collisionCategories = (CollisionCategories.Geom); // Default colide nonphysical don't try to colide with anything From a6b964aa11eb57011b4d85ce16f22c5ac663b1ed Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 29 May 2013 19:51:45 +0100 Subject: [PATCH 07/14] removed spurius ref to ode.dll from odeapi --- OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeApi.cs index 1f09dc76e2..10d7d50d95 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.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetSublevel"), SuppressUnmanagedCodeSecurity] + [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetSublevel"), SuppressUnmanagedCodeSecurity] public static extern void SpaceSetSublevel(IntPtr space, int sublevel); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSweepAndPruneSpaceCreate"), SuppressUnmanagedCodeSecurity] From 4709436a6ca5daecad3f0835fd6c4921df7a5339 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 29 May 2013 20:23:52 +0100 Subject: [PATCH 08/14] retouch prim stopped condition test --- OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index c247e6807f..4cac0aab81 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs @@ -3534,9 +3534,9 @@ namespace OpenSim.Region.Physics.OdePlugin (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 + && (Math.Abs(_orientation.X - ori.X) < 0.0005f) + && (Math.Abs(_orientation.Y - ori.Y) < 0.0005f) + && (Math.Abs(_orientation.Z - ori.Z) < 0.0005f) // ignore W ) { _zeroFlag = true; From 18e4496d2dd41acce1b2183c10499ac24a58e573 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 6 Jun 2013 18:57:32 +0100 Subject: [PATCH 09/14] keyframe: add more locks, change timming stop, added Suspend and resume --- .../Region/Framework/Scenes/KeyframeMotion.cs | 79 +++++++++++++++---- 1 file changed, 64 insertions(+), 15 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs index d773ee7f28..09481a7a6f 100644 --- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs +++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs @@ -245,14 +245,17 @@ namespace OpenSim.Region.Framework.Scenes private void StartTimer() { - KeyframeTimer.Add(this); - m_timerStopped = false; + lock (m_frames) + { + KeyframeTimer.Add(this); + m_timerStopped = false; + } } private void StopTimer() { - m_timerStopped = true; - KeyframeTimer.Remove(this); + lock (m_frames) + m_timerStopped = true; } public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data) @@ -407,19 +410,18 @@ namespace OpenSim.Region.Framework.Scenes } else { - m_running = false; StopTimer(); + m_running = false; } } public void Stop() { + StopTimer(); m_running = false; m_isCrossing = false; m_waitingCrossing = false; - StopTimer(); - m_basePosition = m_group.AbsolutePosition; m_baseRotation = m_group.GroupRotation; @@ -432,14 +434,34 @@ namespace OpenSim.Region.Framework.Scenes public void Pause() { - m_running = false; StopTimer(); + m_running = false; m_group.RootPart.Velocity = Vector3.Zero; m_group.RootPart.AngularVelocity = Vector3.Zero; m_group.SendGroupRootTerseUpdate(); // m_group.RootPart.ScheduleTerseUpdate(); + } + public void Suspend() + { + lock (m_frames) + { + if (m_timerStopped) + return; + m_timerStopped = true; + } + } + + public void Resume() + { + lock (m_frames) + { + if (!m_timerStopped) + return; + if (m_running && !m_waitingCrossing) + StartTimer(); + } } private void GetNextList() @@ -529,6 +551,7 @@ namespace OpenSim.Region.Framework.Scenes pos = (Vector3)k.Position; rot = (Quaternion)k.Rotation; + } m_basePosition = pos; @@ -539,6 +562,35 @@ namespace OpenSim.Region.Framework.Scenes } public void OnTimer(double tickDuration) + { + if (!Monitor.TryEnter(m_frames)) + return; + if (m_timerStopped) + KeyframeTimer.Remove(this); + else + DoOnTimer(tickDuration); + Monitor.Exit(m_frames); + } + + private void Done() + { + KeyframeTimer.Remove(this); + m_timerStopped = true; + m_running = false; + m_isCrossing = false; + m_waitingCrossing = false; + + m_basePosition = m_group.AbsolutePosition; + m_baseRotation = m_group.GroupRotation; + + m_group.RootPart.Velocity = Vector3.Zero; + m_group.RootPart.AngularVelocity = Vector3.Zero; + m_group.SendGroupRootTerseUpdate(); + // m_group.RootPart.ScheduleTerseUpdate(); + m_frames.Clear(); + } + + private void DoOnTimer(double tickDuration) { if (m_skipLoops > 0) { @@ -546,8 +598,6 @@ namespace OpenSim.Region.Framework.Scenes return; } - if (m_timerStopped) // trap events still in air even after a timer.stop - return; if (m_group == null) return; @@ -587,7 +637,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_frames.Count == 0) { - Stop(); + Done(); Scene scene = m_group.Scene; IScriptModule[] scriptModules = scene.RequestModuleInterfaces(); @@ -686,11 +736,10 @@ namespace OpenSim.Region.Framework.Scenes if (angle > 0.01f) */ - if(Math.Abs(step.X - current.X) > 0.001f - || Math.Abs(step.Y - current.Y) > 0.001f + if (Math.Abs(step.X - current.X) > 0.001f + || Math.Abs(step.Y - current.Y) > 0.001f || Math.Abs(step.Z - current.Z) > 0.001f) - // assuming w is a dependente var - + // assuming w is a dependente var { // m_group.UpdateGroupRotationR(step); m_group.RootPart.RotationOffset = step; From c173c2eed52d20916bcafd2b1b6d4a1a24c46105 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 6 Jun 2013 19:21:21 +0100 Subject: [PATCH 10/14] try to suspend and resume keyframes on copy to inventory to take copy doesn't destroy state --- .../InventoryAccess/InventoryAccessModule.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 4c111352c3..a606d76958 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -359,13 +359,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); Dictionary originalPositions = new Dictionary(); + // this possible is not needed if keyframes are saved + Dictionary originalKeyframes = new Dictionary(); foreach (SceneObjectGroup objectGroup in objlist) { if (objectGroup.RootPart.KeyframeMotion != null) - objectGroup.RootPart.KeyframeMotion.Stop(); + { + objectGroup.RootPart.KeyframeMotion.Suspend(); + } objectGroup.RootPart.SetForce(Vector3.Zero); objectGroup.RootPart.SetAngularImpulse(Vector3.Zero, false); + + originalKeyframes[objectGroup.UUID] = objectGroup.RootPart.KeyframeMotion; objectGroup.RootPart.KeyframeMotion = null; Vector3 inventoryStoredPosition = new Vector3 @@ -425,7 +431,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // Restore the position of each group now that it has been stored to inventory. foreach (SceneObjectGroup objectGroup in objlist) + { objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; + objectGroup.RootPart.KeyframeMotion = originalKeyframes[objectGroup.UUID]; + if (objectGroup.RootPart.KeyframeMotion != null) + objectGroup.RootPart.KeyframeMotion.Resume(); + } InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); From ed7fe6239cf53a0a8cacb2ef05e93750a9e22d2b Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 7 Jun 2013 23:18:48 +0100 Subject: [PATCH 11/14] add indexes for new visual parameters shape_hover and APPEARANCEMESSAGE_VERSION. For reference only, this aren't used in sim for now --- OpenSim/Framework/AvatarAppearance.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index b7a0adface..a34c85f531 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -1626,7 +1626,12 @@ namespace OpenSim.Framework BREAST_PHYSICS_LEFTRIGHT_MAX_EFFECT = 247, BREAST_PHYSICS_LEFTRIGHT_SPRING= 248, BREAST_PHYSICS_LEFTRIGHT_GAIN = 249, - BREAST_PHYSICS_LEFTRIGHT_DAMPING = 250 + BREAST_PHYSICS_LEFTRIGHT_DAMPING = 250, + + // Ubit: 07/96/2013 new parameters + _APPEARANCEMESSAGE_VERSION = 251, //ID 11000 + + SHAPE_HOVER = 252, //ID 11001 } #endregion } From d5e04374653f7d4dc96367146933afc7a5c1fbab Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 18 Jul 2014 11:43:31 +0100 Subject: [PATCH 12/14] fix Xengine script instance load --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 04a4e53618..ec35fde2b6 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1325,12 +1325,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine (m_Scripts[itemID].AssetID != assetID)) { lockScriptsForRead(false); - instance = new ScriptInstance(this, part, + instance = new ScriptInstance(this, part, item, startParam, postOnRez, m_MaxScriptQueue); - - if (part.ParentGroup.IsAttachment) appDomain = part.ParentGroup.RootPart.UUID; @@ -1392,8 +1390,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine sandbox = AppDomain.CurrentDomain; } - if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) - return false; +// if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) +// return false; m_AppDomains[appDomain] = sandbox; @@ -1411,9 +1409,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine return false; } } - - instance.Load(m_AppDomains[appDomain], assembly, stateSource); + + if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) + return false; // m_log.DebugFormat( // "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", // part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, From 748fc66ef10591fb0cf3c82d6838561bf48ac197 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 18 Jul 2014 13:19:24 +0100 Subject: [PATCH 13/14] reduce avatar hover in basic ode plugin --- OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 319f6ab884..86735de282 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -500,7 +500,7 @@ namespace OpenSim.Region.Physics.OdePlugin { m_pidControllerActive = true; - m_tainted_CAPSULE_LENGTH = (size.Z * 1.15f) - CAPSULE_RADIUS * 2.0f; + m_tainted_CAPSULE_LENGTH = (size.Z) - CAPSULE_RADIUS * 2.0f; // m_log.Info("[ODE CHARACTER]: " + CAPSULE_LENGTH); } else From 9654b81b2d73e524ad5541bc38440949f4952bad Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 19 Jul 2014 16:16:13 +0100 Subject: [PATCH 14/14] revert to capsule representation of avatar collider --- .../Physics/UbitOdePlugin/ODECharacter.cs | 325 ++---------------- 1 file changed, 28 insertions(+), 297 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index e91299728a..ecd5474079 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -95,10 +95,7 @@ namespace OpenSim.Region.Physics.OdePlugin private float m_feetOffset = 0; private float feetOff = 0; - private float feetSZ = 0.5f; - const float feetScale = 0.8f; private float boneOff = 0; - private float m_lastVelocitySqr = 0; public float walkDivisor = 1.3f; public float runDivisor = 0.8f; @@ -110,7 +107,6 @@ namespace OpenSim.Region.Physics.OdePlugin private bool _zeroFlag = false; - private int m_requestedUpdateFrequency = 0; private uint m_localID = 0; public bool m_returnCollisions = false; // taints and their non-tainted counterparts @@ -127,7 +123,6 @@ namespace OpenSim.Region.Physics.OdePlugin int m_colliderfilter = 0; int m_colliderGroundfilter = 0; int m_colliderObjectfilter = 0; - bool m_collisionException = false; // Default we're a Character private CollisionCategories m_collisionCategories = (CollisionCategories.Character); @@ -140,9 +135,7 @@ namespace OpenSim.Region.Physics.OdePlugin // we do land collisions not ode | CollisionCategories.Land); public IntPtr Body = IntPtr.Zero; private OdeScene _parent_scene; - private IntPtr topbox = IntPtr.Zero; - private IntPtr midbox = IntPtr.Zero; - private IntPtr feetbox = IntPtr.Zero; + private IntPtr capsule = IntPtr.Zero; private IntPtr bbox = IntPtr.Zero; public IntPtr collider = IntPtr.Zero; @@ -150,9 +143,6 @@ namespace OpenSim.Region.Physics.OdePlugin public d.Mass ShellMass; - - - public int m_eventsubscription = 0; private int m_cureventsubscription = 0; private CollisionEventUpdate CollisionEventsThisFrame = null; @@ -214,8 +204,6 @@ namespace OpenSim.Region.Physics.OdePlugin // force lower density for testing m_density = 3.0f; - m_density *= 1.4f; // scale to have mass similar to capsule - mu = parent_scene.AvatarFriction; walkDivisor = walk_divisor; @@ -704,58 +692,6 @@ namespace OpenSim.Region.Physics.OdePlugin AddChange(changes.Momentum, momentum); } - private void ajustCollider() - { - float vq = _velocity.LengthSquared(); - if (m_lastVelocitySqr != vq) - { - m_lastVelocitySqr = vq; - if (vq > 100.0f) - { - Vector3 off = _velocity; - float t = 0.5f * timeStep; - off = off * t; - d.Quaternion qtmp; - d.GeomCopyQuaternion(bbox, out qtmp); - Quaternion q; - q.X = qtmp.X; - q.Y = qtmp.Y; - q.Z = qtmp.Z; - q.W = qtmp.W; - off *= Quaternion.Conjugate(q); - - d.GeomSetOffsetPosition(bbox, off.X, off.Y, off.Z); - - off.X = 2.0f * (m_size.X + Math.Abs(off.X)); - off.Y = 2.0f * (m_size.Y + Math.Abs(off.Y)); - off.Z = m_size.Z + 2.0f * Math.Abs(off.Z); - d.GeomBoxSetLengths(bbox, off.X, off.Y, off.Z); - - d.GeomSetCategoryBits(bbox, (uint)m_collisionCategories); - d.GeomSetCollideBits(bbox, (uint)m_collisionFlags); - d.GeomSetCategoryBits(topbox, 0); - d.GeomSetCollideBits(topbox, 0); - d.GeomSetCategoryBits(midbox, 0); - d.GeomSetCollideBits(midbox, 0); - d.GeomSetCategoryBits(feetbox, 0); - d.GeomSetCollideBits(feetbox, 0); - } - else - { - d.GeomSetCategoryBits(bbox, 0); - d.GeomSetCollideBits(bbox, 0); - d.GeomSetCategoryBits(topbox, (uint)m_collisionCategories); - d.GeomSetCollideBits(topbox, (uint)m_collisionFlags); - d.GeomSetCategoryBits(midbox, (uint)m_collisionCategories); - d.GeomSetCollideBits(midbox, (uint)m_collisionFlags); - d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories); - d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags); - } - uint cat1 = d.GeomGetCategoryBits(bbox); - uint col1 = d.GeomGetCollideBits(bbox); - - } - } private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) { @@ -764,37 +700,14 @@ namespace OpenSim.Region.Physics.OdePlugin float sy = m_size.Y; float sz = m_size.Z; - float topsx = sx * 0.9f; - float midsx = sx; - float feetsx = sx * feetScale; - float bonesx = sx * 0.2f; + float bot = -sz * 0.5f + m_feetOffset; + boneOff = bot + 0.3f; - float topsy = sy * 0.4f; - float midsy = sy; - float feetsy = sy * feetScale * 0.8f; - float bonesy = feetsy * 0.2f; - - float topsz = sz * 0.15f; float feetsz = sz * 0.45f; if (feetsz > 0.6f) feetsz = 0.6f; - float midsz = sz - topsz - feetsz; - float bonesz = sz; - - float bot = -sz * 0.5f + m_feetOffset; - - boneOff = bot + 0.3f; - - float feetz = bot + feetsz * 0.5f; - bot += feetsz; - - feetOff = bot; - feetSZ = feetsz; - - float midz = bot + midsz * 0.5f; - bot += midsz; - float topz = bot + topsz * 0.5f; + feetOff = bot + feetsz; _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace); @@ -805,9 +718,13 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomSetCategoryBits(collider, (uint)m_collisionCategories); d.GeomSetCollideBits(collider, (uint)m_collisionFlags); - feetbox = d.CreateBox(collider, feetsx, feetsy, feetsz); - midbox = d.CreateBox(collider, midsx, midsy, midsz); - topbox = d.CreateBox(collider, topsx, topsy, topsz); + float r = m_size.X; + if (m_size.Y > r) + r = m_size.Y; + float l = m_size.Z - r; + r *= 0.5f; + capsule = d.CreateCapsule(collider, r, l); + bbox = d.CreateBox(collider, m_size.X, m_size.Y, m_size.Z); m_mass = m_density * m_size.X * m_size.Y * m_size.Z; // update mass @@ -820,12 +737,10 @@ namespace OpenSim.Region.Physics.OdePlugin Body = d.BodyCreate(_parent_scene.world); _zeroFlag = false; - m_collisionException = false; m_pidControllerActive = true; m_freemove = false; _velocity = Vector3.Zero; - m_lastVelocitySqr = 0; d.BodySetAutoDisableFlag(Body, false); d.BodySetPosition(Body, npositionX, npositionY, npositionZ); @@ -835,17 +750,9 @@ namespace OpenSim.Region.Physics.OdePlugin _position.Z = npositionZ; d.BodySetMass(Body, ref ShellMass); - d.GeomSetBody(feetbox, Body); - d.GeomSetBody(midbox, Body); - d.GeomSetBody(topbox, Body); + d.GeomSetBody(bbox, Body); - - d.GeomSetOffsetPosition(feetbox, 0, 0, feetz); - d.GeomSetOffsetPosition(midbox, 0, 0, midz); - d.GeomSetOffsetPosition(topbox, 0, 0, topz); - - ajustCollider(); - + d.GeomSetBody(capsule, Body); // The purpose of the AMotor here is to keep the avatar's physical // surrogate from rotating while moving @@ -906,26 +813,12 @@ namespace OpenSim.Region.Physics.OdePlugin } //kill the Geoms - if (topbox != IntPtr.Zero) + if (capsule != IntPtr.Zero) { - _parent_scene.actor_name_map.Remove(topbox); + _parent_scene.actor_name_map.Remove(capsule); _parent_scene.waitForSpaceUnlock(collider); - d.GeomDestroy(topbox); - topbox = IntPtr.Zero; - } - if (midbox != IntPtr.Zero) - { - _parent_scene.actor_name_map.Remove(midbox); - _parent_scene.waitForSpaceUnlock(collider); - d.GeomDestroy(midbox); - midbox = IntPtr.Zero; - } - if (feetbox != IntPtr.Zero) - { - _parent_scene.actor_name_map.Remove(feetbox); - _parent_scene.waitForSpaceUnlock(collider); - d.GeomDestroy(feetbox); - feetbox = IntPtr.Zero; + d.GeomDestroy(capsule); + capsule = IntPtr.Zero; } if (bbox != IntPtr.Zero) @@ -981,163 +874,21 @@ namespace OpenSim.Region.Physics.OdePlugin public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact, ref bool feetcollision) { feetcollision = false; - if (m_collisionException) - return false; Vector3 offset; - if (me == bbox) // if moving fast - { - // force a full inelastic collision - m_collisionException = true; - - offset = m_size * m_orientation2D; - - offset.X = (float)Math.Abs(offset.X) * 0.5f + contact.depth; - offset.Y = (float)Math.Abs(offset.Y) * 0.5f + contact.depth; - offset.Z = (float)Math.Abs(offset.Z) * 0.5f + contact.depth; - - if (reverse) - { - offset.X *= -contact.normal.X; - offset.Y *= -contact.normal.Y; - offset.Z *= -contact.normal.Z; - } - else - { - offset.X *= contact.normal.X; - offset.Y *= contact.normal.Y; - offset.Z *= contact.normal.Z; - } - - offset.X += contact.pos.X; - offset.Y += contact.pos.Y; - offset.Z += contact.pos.Z; - - //_position = offset; - //return false; - } - offset.X = contact.pos.X - _position.X; offset.Y = contact.pos.Y - _position.Y; - if (me == topbox) - { - offset.Z = contact.pos.Z - _position.Z; - - offset.Normalize(); - - if (reverse) - { - contact.normal.X = offset.X; - contact.normal.Y = offset.Y; - contact.normal.Z = offset.Z; - } - else - { - contact.normal.X = -offset.X; - contact.normal.Y = -offset.Y; - contact.normal.Z = -offset.Z; - } - return true; - } - - if (me == midbox) - { - if (Math.Abs(contact.normal.Z) > 0.95f) - { - offset.Z = contact.pos.Z - _position.Z; - offset.X = (float)Math.Abs(offset.X) * 0.5f + contact.depth; - offset.Y = (float)Math.Abs(offset.Y) * 0.5f + contact.depth; - offset.Z = (float)Math.Abs(offset.Z) * 0.5f + contact.depth; - - if (reverse) - { - offset.X *= -contact.normal.X; - offset.Y *= -contact.normal.Y; - offset.Z *= -contact.normal.Z; - } - else - { - offset.X *= contact.normal.X; - offset.Y *= contact.normal.Y; - offset.Z *= contact.normal.Z; - } - - offset.X += contact.pos.X; - offset.Y += contact.pos.Y; - offset.Z += contact.pos.Z; - _position = offset; - return true; - } - else - offset.Z = contact.normal.Z; - - offset.Normalize(); - - /* - if (reverse) - { - contact.normal.X = offset.X; - contact.normal.Y = offset.Y; - contact.normal.Z = offset.Z; - } - else - { - contact.normal.X = -offset.X; - contact.normal.Y = -offset.Y; - contact.normal.Z = -offset.Z; - } - */ - //_position.Z = offset.Z; - return true; - } - - else if (me == feetbox) + if (me == capsule) { float h = contact.pos.Z - _position.Z; - - // Only do this if the normal is sufficiently pointing in the 'up' direction - if (Math.Abs(contact.normal.Z) > 0.95f) - { - // We Only want to do this if we're sunk into the object a bit and we're stuck and we're trying to move and feetcollision is false - if ((contact.depth > 0.0010f && _velocity.X == 0f && _velocity.Y == 0 && _velocity.Z == 0) - && (_target_velocity.X > 0 || _target_velocity.Y > 0 || _target_velocity.Z > 0) - && (!feetcollision) ) - { - m_collisionException = true; // Stop looping, do this only once not X times Contacts - _position.Z += contact.depth + 0.01f; // Move us Up the amount that we sank in, and add 0.01 meters to gently lift avatar up. - - return true; - } - - if (contact.normal.Z > 0) - contact.normal.Z = 1.0f; - else - contact.normal.Z = -1.0f; - contact.normal.X = 0.0f; - contact.normal.Y = 0.0f; - feetcollision = true; - if (h < boneOff) - IsColliding = true; - return true; - } - - offset.Z = h - feetOff; // distance from top of feetbox + offset.Z = h - feetOff; if (offset.Z > 0) - return false; + return true; - if (offset.Z > -0.01) - { - offset.X = 0; - offset.Y = 0; - offset.Z = -1.0f; - } - else - { - offset.Normalize(); - } + offset.Normalize(); if (reverse) { @@ -1171,23 +922,6 @@ namespace OpenSim.Region.Physics.OdePlugin if (Body == IntPtr.Zero) return; - if (m_collisionException) - { - d.BodySetPosition(Body,_position.X, _position.Y, _position.Z); - d.BodySetLinearVel(Body, 0, 0, 0); - - float v = _velocity.Length(); - if (v != 0) - { - v = 5.0f / v; - _velocity = _velocity * v; - d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); - } - ajustCollider(); - m_collisionException = false; - return; - } - d.Vector3 dtmp = d.BodyGetPosition(Body); Vector3 localpos = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); @@ -1263,7 +997,8 @@ namespace OpenSim.Region.Physics.OdePlugin // colide with land d.AABB aabb; - d.GeomGetAABB(feetbox, out aabb); +// d.GeomGetAABB(feetbox, out aabb); + d.GeomGetAABB(capsule, out aabb); float chrminZ = aabb.MinZ; ; // move up a bit Vector3 posch = localpos; @@ -1489,7 +1224,6 @@ namespace OpenSim.Region.Physics.OdePlugin m_rotationalVelocity.Z = dtmp.Z; Math.Round(m_rotationalVelocity.Z,3); } - ajustCollider(); } public void round(ref Vector3 v, int digits) @@ -1655,10 +1389,11 @@ namespace OpenSim.Region.Physics.OdePlugin AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z); _parent_scene.actor_name_map[collider] = (PhysicsActor)this; - _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this; - _parent_scene.actor_name_map[midbox] = (PhysicsActor)this; - _parent_scene.actor_name_map[topbox] = (PhysicsActor)this; +// _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this; +// _parent_scene.actor_name_map[midbox] = (PhysicsActor)this; +// _parent_scene.actor_name_map[topbox] = (PhysicsActor)this; _parent_scene.actor_name_map[bbox] = (PhysicsActor)this; + _parent_scene.actor_name_map[capsule] = (PhysicsActor)this; _parent_scene.AddCharacter(this); } else @@ -1714,13 +1449,10 @@ namespace OpenSim.Region.Physics.OdePlugin _parent_scene.actor_name_map[collider] = (PhysicsActor)this; - _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this; - _parent_scene.actor_name_map[midbox] = (PhysicsActor)this; - _parent_scene.actor_name_map[topbox] = (PhysicsActor)this; _parent_scene.actor_name_map[bbox] = (PhysicsActor)this; + _parent_scene.actor_name_map[capsule] = (PhysicsActor)this; } m_freemove = false; - m_collisionException = false; m_pidControllerActive = true; } else @@ -1851,7 +1583,6 @@ namespace OpenSim.Region.Physics.OdePlugin if (Body != IntPtr.Zero) d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z); - ajustCollider(); } private void donullchange()