From 8bea3dbdb91dfb465338572e3dfb40a5adfb9bab Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Mon, 10 Mar 2008 05:23:43 +0000 Subject: [PATCH] * Added ODEPlugin Support for llSetBuoyancy. Set Buoyancy to 1 for space prim. * Added WaterLevel support to the ODEPlugin. More on this later. --- .../ClientStack/RegionApplicationBase.cs | 1 + .../Environment/Scenes/SceneObjectPart.cs | 8 ++ .../BasicPhysicsPlugin/BasicPhysicsPlugin.cs | 11 ++ .../Physics/BulletXPlugin/BulletXPlugin.cs | 12 ++ .../Region/Physics/Manager/PhysicsActor.cs | 6 + .../Region/Physics/Manager/PhysicsScene.cs | 6 + .../Region/Physics/OdePlugin/ODECharacter.cs | 7 + OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 49 ++++++- OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 128 ++++++++++++++++-- OpenSim/Region/Physics/POSPlugin/POSPlugin.cs | 17 +++ .../Region/Physics/PhysXPlugin/PhysXPlugin.cs | 17 +++ .../Common/LSL_BuiltIn_Commands.cs | 8 +- .../Common/LSL_BuiltIn_Commands_Interface.cs | 1 + 13 files changed, 259 insertions(+), 12 deletions(-) diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs index 43f630db20..ecb15914fc 100644 --- a/OpenSim/Region/ClientStack/RegionApplicationBase.cs +++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs @@ -127,6 +127,7 @@ namespace OpenSim.Region.ClientStack scene.PhysicsScene = GetPhysicsScene(); scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); + scene.PhysicsScene.SetWaterLevel(regionInfo.EstateSettings.waterHeight); //Master Avatar Setup UserProfileData masterAvatar; diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index b7b788343c..a8f08ecd3d 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -934,6 +934,14 @@ namespace OpenSim.Region.Environment.Scenes m_sitTargetOrientation = orientation; } + public void SetBuoyancy(float fvalue) + { + if (PhysActor != null) + { + PhysActor.Buoyancy = fvalue; + } + } + public LLVector3 GetSitTargetPositionLL() { return new LLVector3(m_sitTargetPosition.x, m_sitTargetPosition.y, m_sitTargetPosition.z); diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs index c7ccef37a6..2b4bbc4cb9 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs @@ -189,6 +189,11 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin _heightMap = heightMap; } + public override void SetWaterLevel(float baseheight) + { + + } + public override void DeleteTerrain() { } @@ -243,6 +248,12 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin set { return; } } + public override float Buoyancy + { + get { return 0f; } + set { return; } + } + public override bool IsPhysical { get { return false; } diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs index 12e2ea2663..feb9ca1174 100644 --- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs +++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs @@ -412,6 +412,12 @@ namespace OpenSim.Region.Physics.BulletXPlugin { } + + public override void SetWaterLevel(float baseheight) + { + + } + public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size) { PhysicsVector pos = new PhysicsVector(); @@ -918,6 +924,12 @@ namespace OpenSim.Region.Physics.BulletXPlugin set { return; } } + public override float Buoyancy + { + get { return 0f; } + set { return; } + } + public virtual void SetAcceleration(PhysicsVector accel) { lock (BulletXScene.BulletXLock) diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index e31a08da14..82b7450ba2 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -208,6 +208,8 @@ namespace OpenSim.Region.Physics.Manager public abstract bool Kinematic { get; set; } + public abstract float Buoyancy { get; set; } + public abstract void AddForce(PhysicsVector force); public abstract void SetMomentum(PhysicsVector momentum); @@ -249,6 +251,10 @@ namespace OpenSim.Region.Physics.Manager set { return; } } + public override float Buoyancy { + get { return 0f; } + set { return; } + } public override bool CollidingGround { diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 996aed640b..a51b2dff79 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -79,6 +79,8 @@ namespace OpenSim.Region.Physics.Manager public abstract void SetTerrain(float[] heightMap); + public abstract void SetWaterLevel(float baseheight); + public abstract void DeleteTerrain(); public abstract void Dispose(); @@ -108,6 +110,10 @@ namespace OpenSim.Region.Physics.Manager public override void RemovePrim(PhysicsActor prim) { } + public override void SetWaterLevel(float baseheight) + { + + } /* public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation) diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index b5263a650f..7047ec1037 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -87,6 +87,8 @@ namespace OpenSim.Region.Physics.OdePlugin private bool m_hackSentFly = false; public uint m_localID = 0; + private float m_buoyancy = 0f; + private CollisionLocker ode; private string m_name = String.Empty; @@ -177,6 +179,11 @@ namespace OpenSim.Region.Physics.OdePlugin set { return; } } + public override float Buoyancy + { + get { return m_buoyancy; } + set { m_buoyancy = value; } + } public override bool IsPhysical { diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index c5ffe98d10..5291cbff60 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -55,7 +55,8 @@ namespace OpenSim.Region.Physics.OdePlugin private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom | CollisionCategories.Space | CollisionCategories.Body - | CollisionCategories.Character); + | CollisionCategories.Character + ); private bool m_taintshape = false; private bool m_taintPhysics = false; private bool m_collidesLand = true; @@ -106,6 +107,8 @@ namespace OpenSim.Region.Physics.OdePlugin public int m_roundsUnderMotionThreshold = 0; private int m_crossingfailures = 0; + public float m_buoyancy = 0f; + public bool outofBounds = false; private float m_density = 10.000006836f; // Aluminum g/cm3; @@ -704,7 +707,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (prim_geom != (IntPtr)0) { if (m_taintposition != _position) - Move(timestep); + changemove(timestep); if (m_taintrot != _orientation) rotate(timestep); @@ -829,7 +832,10 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } if (m_isphysical) + { + d.BodySetLinearVel(Body, 0f, 0f, 0f); enableBodySoft(); + } } @@ -1003,7 +1009,7 @@ namespace OpenSim.Region.Physics.OdePlugin } - public void Move(float timestep) + public void changemove(float timestep) { @@ -1063,6 +1069,37 @@ namespace OpenSim.Region.Physics.OdePlugin m_taintposition = _position; } + public void Move(float timestep) + { + + if (IsPhysical && Body != (IntPtr)0 && !m_isSelected) + { + float m_mass = CalculateMass(); + //m_log.Info(m_collisionFlags.ToString()); + if (m_buoyancy != 0) + { + float buoyancy = 0f; + if (m_buoyancy > 0) + { + buoyancy = ((9.8f * m_buoyancy) * m_mass); + + //d.Vector3 l_velocity = d.BodyGetLinearVel(Body); + //m_log.Info("Using Buoyancy: " + buoyancy + " G: " + (9.8f * m_buoyancy) + "mass:" + m_mass + " Pos: " + Position.ToString()); + } + else + { + buoyancy = (-1 * ((9.8f * (-1 * m_buoyancy)) * m_mass)); + } + d.BodyAddForce(Body, 0, 0, buoyancy); + + } + } + else + { + return; + } + } + public void rotate(float timestep) { @@ -1676,6 +1713,12 @@ namespace OpenSim.Region.Physics.OdePlugin } } + public override float Buoyancy + { + get { return m_buoyancy; } + set { m_buoyancy = value; } + } + public override void link(PhysicsActor obj) { m_taintparent = obj; diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 16c6bb059c..9f160a5748 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -49,6 +49,7 @@ namespace OpenSim.Region.Physics.OdePlugin private CollisionLocker ode; private OdeScene _mScene; + public OdePlugin() { ode = new CollisionLocker(); @@ -98,16 +99,26 @@ namespace OpenSim.Region.Physics.OdePlugin private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); CollisionLocker ode; - + + protected Random fluidRandomizer = new Random(System.Environment.TickCount); + private const uint m_regionWidth = Constants.RegionSize; private const uint m_regionHeight = Constants.RegionSize; private static float ODE_STEPSIZE = 0.020f; private static float metersInSpace = 29.9f; + private float waterlevel = 0f; + private int framecount = 0; private IntPtr contactgroup; private IntPtr LandGeom = (IntPtr) 0; + + private IntPtr WaterGeom = (IntPtr)0; + private float[] _heightmap; + + private float[] _watermap; + private float[] _origheightmap; private d.NearCallback nearCallback; @@ -120,13 +131,15 @@ namespace OpenSim.Region.Physics.OdePlugin public Dictionary geom_name_map = new Dictionary(); public Dictionary actor_name_map = new Dictionary(); private d.ContactGeom[] contacts = new d.ContactGeom[80]; + private d.Contact contact; private d.Contact TerrainContact; private d.Contact AvatarMovementprimContact; private d.Contact AvatarMovementTerrainContact; + private d.Contact WaterContact; - + private int m_randomizeWater = 200; private int m_physicsiterations = 10; private float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag private PhysicsActor PANull = new NullPhysicsActor(); @@ -176,6 +189,12 @@ namespace OpenSim.Region.Physics.OdePlugin TerrainContact.surface.bounce = 0.1f; TerrainContact.surface.soft_erp = 0.1025f; + WaterContact.surface.mode |= (d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM); + WaterContact.surface.mu = 0f; // No friction + WaterContact.surface.bounce = 0.0f; // No bounce + WaterContact.surface.soft_cfm = 0.01f; + WaterContact.surface.soft_erp = 0.010f; + // Prim contact friction and bounce // THis is the *non* moving version of friction and bounce // Use this when an avatar comes in contact with a prim @@ -187,8 +206,8 @@ namespace OpenSim.Region.Physics.OdePlugin // Use this when an avatar is in contact with the terrain and moving. AvatarMovementTerrainContact.surface.mode |= d.ContactFlags.SoftERP; AvatarMovementTerrainContact.surface.mu = 75.0f; - AvatarMovementTerrainContact.surface.bounce = 0.1f; - AvatarMovementTerrainContact.surface.soft_erp = 0.1025f; + AvatarMovementTerrainContact.surface.bounce = 0.05f; + AvatarMovementTerrainContact.surface.soft_erp = 0.05025f; lock (OdeLock) { @@ -216,7 +235,7 @@ namespace OpenSim.Region.Physics.OdePlugin // zero out a heightmap array float array (single dimention [flattened])) _heightmap = new float[514*514]; - + _watermap = new float[258 * 258]; // Zero out the prim spaces array (we split our space into smaller spaces so // we can hit test less. @@ -571,12 +590,36 @@ namespace OpenSim.Region.Physics.OdePlugin joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); } } + else if (name1 == "Water" || name2 == "Water") + { + if ((p2.PhysicsActorType == (int)ActorTypes.Prim)) + { + + } + else + { + + } + WaterContact.surface.soft_cfm = 0.0000f; + WaterContact.surface.soft_erp = 0.00000f; + if (contacts[i].depth > 0.1f) + { + contacts[i].depth *= 52; + //contacts[i].normal = new d.Vector3(0, 0, 1); + //contacts[i].pos = new d.Vector3(0, 0, contacts[i].pos.Z - 5f); + } + WaterContact.geom = contacts[i]; + + joint = d.JointCreateContact(world, contactgroup, ref WaterContact); + + //m_log.Info("[PHYSICS]: Prim Water Contact" + contacts[i].depth); + } else { // we're colliding with prim or avatar // check if we're moving - if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && + if ((p2.PhysicsActorType == (int)ActorTypes.Agent) && (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) { // Use the Movement prim contact @@ -1279,6 +1322,11 @@ namespace OpenSim.Region.Physics.OdePlugin /// public override float Simulate(float timeStep) { + if (framecount >= int.MaxValue) + framecount = 0; + + framecount++; + float fps = 0; //m_log.Info(timeStep.ToString()); step_time += timeStep; @@ -1369,11 +1417,12 @@ namespace OpenSim.Region.Physics.OdePlugin foreach (OdePrim prim in _activeprims) { prim.m_collisionscore = 0; + prim.Move(timeStep); } } - - + //if ((framecount % m_randomizeWater) == 0) + // randomizeWater(waterlevel); collision_optimized(timeStep); @@ -1772,6 +1821,69 @@ namespace OpenSim.Region.Physics.OdePlugin { } + public override void SetWaterLevel(float baseheight) + { + waterlevel = baseheight; + randomizeWater(waterlevel); + } + + public void randomizeWater(float baseheight) + { + const uint heightmapWidth = m_regionWidth + 2; + const uint heightmapHeight = m_regionHeight + 2; + const uint heightmapWidthSamples = m_regionWidth + 2; + const uint heightmapHeightSamples = m_regionHeight + 2; + const float scale = 1.0f; + const float offset = 0.0f; + const float thickness = 2.9f; + const int wrap = 0; + + for (int i = 0; i < (258 * 258); i++) + { + _watermap[i] = (baseheight-0.1f) + ((float)fluidRandomizer.Next(1,9) / 10f); + // m_log.Info((baseheight - 0.1f) + ((float)fluidRandomizer.Next(1, 9) / 10f)); + } + + + lock (OdeLock) + { + if (!(WaterGeom == (IntPtr)0)) + { + d.SpaceRemove(space, WaterGeom); + } + IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); + d.GeomHeightfieldDataBuildSingle(HeightmapData, _watermap, 0, heightmapWidth, heightmapHeight, + (int)heightmapWidthSamples, (int)heightmapHeightSamples, scale, + offset, thickness, wrap); + d.GeomHeightfieldDataSetBounds(HeightmapData, m_regionWidth, m_regionHeight); + WaterGeom = d.CreateHeightfield(space, HeightmapData, 1); + if (WaterGeom != (IntPtr)0) + { + d.GeomSetCategoryBits(WaterGeom, (int)(CollisionCategories.Water)); + d.GeomSetCollideBits(WaterGeom, (int)(CollisionCategories.Space)); + + } + geom_name_map[WaterGeom] = "Water"; + + d.Matrix3 R = new d.Matrix3(); + + Quaternion q1 = Quaternion.FromAngleAxis(1.5707f, new Vector3(1, 0, 0)); + Quaternion q2 = Quaternion.FromAngleAxis(1.5707f, new Vector3(0, 1, 0)); + //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1)); + + q1 = q1 * q2; + //q1 = q1 * q3; + Vector3 v3 = new Vector3(); + float angle = 0; + q1.ToAngleAxis(ref angle, ref v3); + + d.RFromAxisAndAngle(out R, v3.x, v3.y, v3.z, angle); + d.GeomSetRotation(WaterGeom, ref R); + d.GeomSetPosition(WaterGeom, 128, 128, 0); + } + + } + public override void Dispose() { lock (OdeLock) diff --git a/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs b/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs index ac63a124ff..dd2c0ddde6 100644 --- a/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs +++ b/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs @@ -89,6 +89,11 @@ namespace OpenSim.Region.Physics.POSPlugin return act; } + public override void SetWaterLevel(float baseheight) + { + + } + public override void RemovePrim(PhysicsActor prim) { POSPrim p = (POSPrim) prim; @@ -372,6 +377,12 @@ namespace OpenSim.Region.Physics.POSPlugin set { return; } } + public override float Buoyancy + { + get { return 0f; } + set { return; } + } + public override bool IsPhysical { get { return false; } @@ -605,6 +616,12 @@ namespace OpenSim.Region.Physics.POSPlugin set { return; } } + public override float Buoyancy + { + get { return 0f; } + set { return; } + } + public override PhysicsVector Velocity { get { return _velocity; } diff --git a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs index 0c4226060d..b03da3168e 100644 --- a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs +++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs @@ -93,6 +93,11 @@ namespace OpenSim.Region.Physics.PhysXPlugin } + public override void SetWaterLevel(float baseheight) + { + + } + public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size) { Vec3 pos = new Vec3(); @@ -242,6 +247,12 @@ namespace OpenSim.Region.Physics.PhysXPlugin set { return; } } + public override float Buoyancy + { + get { return 0f; } + set { return; } + } + public override bool IsPhysical { get { return false; } @@ -467,6 +478,12 @@ namespace OpenSim.Region.Physics.PhysXPlugin set { return; } } + public override float Buoyancy + { + get { return 0f; } + set { return; } + } + public override bool ThrottleUpdates { get { return false; } diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs index 17fd862b4e..010961e069 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs @@ -1499,7 +1499,13 @@ namespace OpenSim.Region.ScriptEngine.Common public void llSetBuoyancy(double buoyancy) { m_host.AddScriptLPS(1); - NotImplemented("llSetBuoyancy"); + if (m_host.ParentGroup != null) + { + if (m_host.ParentGroup.RootPart != null) + { + m_host.ParentGroup.RootPart.SetBuoyancy((float)buoyancy); + } + } } public void llSetHoverHeight(double height, int water, double tau) diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs index c6d683c42f..d60d70e908 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs @@ -648,5 +648,6 @@ namespace OpenSim.Region.ScriptEngine.Common void osRegionNotice(string msg); bool osConsoleCommand(string Command); void osSetParcelMediaURL(string url); + } }