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 } diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index fadcd5eecf..d5c2fd4908 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -358,14 +358,20 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess bool asAttachment) { CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); -// Dictionary originalPositions = new Dictionary(); + 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 @@ -427,9 +433,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess else itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment); -// // Restore the position of each group now that it has been stored to inventory. -// foreach (SceneObjectGroup objectGroup in objlist) -// objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; + // 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); diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs index 4d153da9d0..49b71e5a30 100644 --- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs +++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs @@ -265,14 +265,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) @@ -427,19 +430,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; @@ -452,14 +454,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() @@ -550,6 +572,7 @@ namespace OpenSim.Region.Framework.Scenes pos = (Vector3)k.Position; rot = (Quaternion)k.Rotation; + } m_basePosition = pos; @@ -560,6 +583,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) { @@ -567,8 +619,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; @@ -608,7 +658,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_frames.Count == 0) { - Stop(); + Done(); Scene scene = m_group.Scene; IScriptModule[] scriptModules = scene.RequestModuleInterfaces(); @@ -707,11 +757,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; 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; diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 6938e553e3..d67d4d2d8d 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -918,6 +918,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 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 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/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() 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/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..4cac0aab81 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 * * */ @@ -115,7 +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 private CollisionCategories m_collisionCategories = (CollisionCategories.Geom); @@ -914,6 +914,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); @@ -1736,7 +1785,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 +2195,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 +2413,7 @@ namespace OpenSim.Region.Physics.OdePlugin MakeBody(); } + #region changes private void changeadd() @@ -3213,7 +3265,6 @@ namespace OpenSim.Region.Physics.OdePlugin if (++bodydisablecontrol < 20) return; - d.BodyEnable(Body); } @@ -3334,7 +3385,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; @@ -3381,11 +3432,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 +3530,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.0005f) + && (Math.Abs(_orientation.Y - ori.Y) < 0.0005f) + && (Math.Abs(_orientation.Z - ori.Z) < 0.0005f) // ignore W ) { _zeroFlag = true; @@ -3499,9 +3551,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 +3590,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 +3617,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/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 754bc86978..8abf6cf73d 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 | d.ContactFlags.Slip1 | d.ContactFlags.Slip2; + const float comumContactERP = 0.7f; const float comumContactCFM = 0.0001f; + const float comumContactSLIP = 0f; 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; @@ -428,11 +411,9 @@ 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 - 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); } } } diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 2713080655..452c4437a3 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,