From 27e028752600921deac57e281f1df6d8c7310c5d Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Wed, 19 Dec 2007 22:42:06 +0000 Subject: * Re-did the mass calculations in ODE for Prim * Exposed the mass as a PhysicsActor read only property (so scripts can get at it - hint hint -) * Hollow and Path Cuts affect the prim mass (all Hollow Types are supported in this calculation (sphere,square,triangle)) * Prim no longer sink into the ground. --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 124 ++++++++++++++++++++++++++-- 1 file changed, 118 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/Physics/OdePlugin/ODEPrim.cs') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 2ec8131..26cb24b 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -65,6 +65,9 @@ namespace OpenSim.Region.Physics.OdePlugin private bool m_throttleUpdates = false; private int throttleCounter = 0; public bool outofBounds = false; + private float m_density = 0f; + + public bool _zeroFlag = false; private bool m_lastUpdateSent = false; @@ -73,7 +76,7 @@ namespace OpenSim.Region.Physics.OdePlugin private String m_primName; private PhysicsVector _target_velocity; public d.Mass pMass; - private const float MassMultiplier = 150f; // Ref: Water: 1000kg.. this iset to 500 + private const float MassMultiplier = 150f; private int debugcounter = 0; public OdePrim(String primName, OdeScene parent_scene, IntPtr targetSpace, PhysicsVector pos, PhysicsVector size, @@ -182,15 +185,104 @@ namespace OpenSim.Region.Physics.OdePlugin _parent_scene.addActivePrim(this); } - public void setMass() + private float CalculateMass() { - //Sets Mass based on member MassMultiplier. + float volume = 0; + + // No material is passed to the physics engines yet.. soo.. + float density = 2.7f; // Aluminum g/cm3; + + float returnMass = 0; + + switch (_pbs.ProfileShape) + { + case ProfileShape.Square: + // Profile Volume + + volume = _size.X * _size.Y * _size.Z; + + // If the user has 'hollowed out' + if (((float)_pbs.ProfileHollow / 50000f) > 0.0) + { + float hollowAmount = (float)_pbs.ProfileHollow / 50000f; + //break; + float hollowVolume = 0; + switch (_pbs.HollowShape) + { + case HollowShape.Square: + case HollowShape.Same: + // Cube Hollow + float hollowsizex = _size.X * hollowAmount; + float hollowsizey = _size.Y * hollowAmount; + float hollowsizez = _size.Z * hollowAmount; + hollowVolume = hollowsizex * hollowsizey * hollowsizez; + break; + + case HollowShape.Circle: + // Hollow shape is a perfect cyllinder in respect to the cube's scale + float hRadius = _size.X / 2; + float hLength = _size.Z; + + // pi * r2 * h + hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount); + break; + + case HollowShape.Triangle: + float aLength = _size.Y; // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y + // 1/2 abh + hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount); + break; + + default: + hollowVolume = 0; + break; + } + volume = volume - hollowVolume; + + } + + break; + + default: + volume = _size.X * _size.Y * _size.Z; + break; + } + + // Calculate Path cut effect on volume + // Not exact, in the triangle hollow example + // They should ever be less then zero.. + // we'll ignore it if it's less then zero + float PathCutEndAmount = _pbs.ProfileEnd; + float PathCutStartAmount = _pbs.ProfileBegin; + if (((PathCutStartAmount + PathCutEndAmount)/50000f) > 0.0f) + { + + float pathCutAmount = ((PathCutStartAmount + PathCutEndAmount) / 50000f); + + if (pathCutAmount >= 0.99f) + pathCutAmount=0.99f; + + volume = volume - (volume * pathCutAmount); + } + + returnMass = density * volume; + + return returnMass; + } + + public void setMass() + { if (Body != (IntPtr)0) { - d.MassSetBox(out pMass, (_size.X * _size.Y * _size.Z * MassMultiplier), _size.X, _size.Y, _size.Z); + //if (_pbs.ProfileShape = ProfileShape.Square) { + + d.MassSetBoxTotal(out pMass, CalculateMass(), _size.X, _size.Y, _size.Z); d.BodySetMass(Body, ref pMass); } } + + + public void disableBody() { //this kills the body so things like 'mesh' can re-create it. @@ -212,7 +304,7 @@ namespace OpenSim.Region.Physics.OdePlugin int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage int VertexCount = vertexList.GetLength(0) / 3; int IndexCount = indexList.GetLength(0); - + _triMeshData = d.GeomTriMeshDataCreate(); d.GeomTriMeshDataBuildSimple(_triMeshData, vertexList, 3 * sizeof(float), VertexCount, indexList, IndexCount, @@ -220,7 +312,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomTriMeshDataPreprocess(_triMeshData); prim_geom = d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null); - + if (IsPhysical && Body == (IntPtr)0) { // Recreate the body @@ -502,6 +594,26 @@ namespace OpenSim.Region.Physics.OdePlugin } } + public override float Mass + { + get { return CalculateMass(); } + } + + public override PhysicsVector Force + { + get { return PhysicsVector.Zero; } + } + + public override PhysicsVector CenterOfMass + { + get { return PhysicsVector.Zero; } + } + + public override PhysicsVector GeometricCenter + { + get { return PhysicsVector.Zero; } + } + public override PrimitiveBaseShape Shape { set -- cgit v1.1