From 21d44230305903d4702fb1809a43611d2ef60a2a Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Mon, 20 Apr 2009 03:07:53 +0000 Subject: * Allow passing of material type to physics engine * Define low friction and medium bounce for Glass --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 9 +- OpenSim/Region/Physics/Manager/PhysicsActor.cs | 10 + OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 7 + OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 260 +++++++++++++++++++-- 4 files changed, 266 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 1a5dd6d..f5ae94f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -421,7 +421,14 @@ namespace OpenSim.Region.Framework.Scenes public byte Material { get { return (byte) m_material; } - set { m_material = (Material)value; } + set + { + m_material = (Material)value; + if (PhysActor != null) + { + PhysActor.SetMaterial((int)value); + } + } } public ulong RegionHandle diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index c4bb889..4a4c294 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -182,6 +182,11 @@ namespace OpenSim.Region.Physics.Manager } } + public virtual void SetMaterial (int material) + { + + } + public abstract PhysicsVector Position { get; set; } public abstract float Mass { get; } public abstract PhysicsVector Force { get; set; } @@ -334,6 +339,11 @@ namespace OpenSim.Region.Physics.Manager } + public override void SetMaterial(int material) + { + + } + public override PhysicsVector CenterOfMass { get { return PhysicsVector.Zero; } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index adb559a..7b3d18f 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -169,6 +169,8 @@ namespace OpenSim.Region.Physics.OdePlugin private ODEVehicleSettings m_vehicle; + internal int m_material = (int)Material.Wood; + public OdePrim(String primName, OdeScene parent_scene, PhysicsVector pos, PhysicsVector size, Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) { @@ -3096,5 +3098,10 @@ namespace OpenSim.Region.Physics.OdePlugin dst.I.M22 = src.I.M22; } + public override void SetMaterial(int pMaterial) + { + m_material = pMaterial; + } + } } diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 1abedf5..178e6fd 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -123,6 +123,28 @@ namespace OpenSim.Region.Physics.OdePlugin Selected = 0x00000100 } + /// + /// Material type for a primitive + /// + public enum Material : int + { + /// + Stone = 0, + /// + Metal = 1, + /// + Glass = 2, + /// + Wood = 3, + /// + Flesh = 4, + /// + Plastic = 5, + /// + Rubber = 6 + + } + public sealed class OdeScene : PhysicsScene { private readonly ILog m_log; @@ -239,6 +261,7 @@ namespace OpenSim.Region.Physics.OdePlugin private d.Contact AvatarMovementprimContact; private d.Contact AvatarMovementTerrainContact; private d.Contact WaterContact; + private d.Contact[,] m_materialContacts; //Ckrinke: Comment out until used. We declare it, initialize it, but do not use it //Ckrinke private int m_randomizeWater = 200; @@ -319,6 +342,11 @@ namespace OpenSim.Region.Physics.OdePlugin _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. } @@ -479,6 +507,131 @@ namespace OpenSim.Region.Physics.OdePlugin AvatarMovementTerrainContact.surface.bounce = mTerrainContactBounce; AvatarMovementTerrainContact.surface.soft_erp = mTerrainContactERP; + + /* + + Stone = 0, + /// + Metal = 1, + /// + Glass = 2, + /// + Wood = 3, + /// + Flesh = 4, + /// + Plastic = 5, + /// + Rubber = 6 + */ + + m_materialContacts = new d.Contact[7,2]; + + m_materialContacts[(int)Material.Stone, 0] = new d.Contact(); + m_materialContacts[(int)Material.Stone, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Stone, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Stone, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Stone, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Stone, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Stone, 1] = new d.Contact(); + m_materialContacts[(int)Material.Stone, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Stone, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Stone, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Stone, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Stone, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Metal, 0] = new d.Contact(); + m_materialContacts[(int)Material.Metal, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Metal, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Metal, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Metal, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Metal, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Metal, 1] = new d.Contact(); + m_materialContacts[(int)Material.Metal, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Metal, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Metal, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Metal, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Metal, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Glass, 0] = new d.Contact(); + m_materialContacts[(int)Material.Glass, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Glass, 0].surface.mu = 1f; + m_materialContacts[(int)Material.Glass, 0].surface.bounce = 0.5f; + m_materialContacts[(int)Material.Glass, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Glass, 0].surface.soft_erp = 0.010f; + + /* + private float nmAvatarObjectContactFriction = 250f; + private float nmAvatarObjectContactBounce = 0.1f; + + private float mAvatarObjectContactFriction = 75f; + private float mAvatarObjectContactBounce = 0.1f; + */ + m_materialContacts[(int)Material.Glass, 1] = new d.Contact(); + m_materialContacts[(int)Material.Glass, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Glass, 1].surface.mu = 1f; + m_materialContacts[(int)Material.Glass, 1].surface.bounce = 0.5f; + m_materialContacts[(int)Material.Glass, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Glass, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Wood, 0] = new d.Contact(); + m_materialContacts[(int)Material.Wood, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Wood, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Wood, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Wood, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Wood, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Wood, 1] = new d.Contact(); + m_materialContacts[(int)Material.Wood, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Wood, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Wood, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Wood, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Wood, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Flesh, 0] = new d.Contact(); + m_materialContacts[(int)Material.Flesh, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Flesh, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Flesh, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Flesh, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Flesh, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Flesh, 1] = new d.Contact(); + m_materialContacts[(int)Material.Flesh, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Flesh, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Flesh, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Flesh, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Flesh, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Plastic, 0] = new d.Contact(); + m_materialContacts[(int)Material.Plastic, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Plastic, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Plastic, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Plastic, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Plastic, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Plastic, 1] = new d.Contact(); + m_materialContacts[(int)Material.Plastic, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Plastic, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Plastic, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Plastic, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Plastic, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Rubber, 0] = new d.Contact(); + m_materialContacts[(int)Material.Rubber, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Rubber, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Rubber, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Rubber, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Rubber, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Rubber, 1] = new d.Contact(); + m_materialContacts[(int)Material.Rubber, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Rubber, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Rubber, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Rubber, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Rubber, 1].surface.soft_erp = 0.010f; + d.HashSpaceSetLevels(space, worldHashspaceLow, worldHashspaceHigh); // Set the gravity,, don't disable things automatically (we set it explicitly on some things) @@ -869,13 +1022,63 @@ namespace OpenSim.Region.Physics.OdePlugin } else { - // Use the non moving terrain contact - TerrainContact.geom = contacts[i]; - _perloopContact.Add(contacts[i]); - if (m_global_contactcount < maxContactsbeforedeath) + if (p2.PhysicsActorType == (int)ActorTypes.Agent) { - joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); - m_global_contactcount++; + // Use the non moving terrain contact + TerrainContact.geom = contacts[i]; + _perloopContact.Add(contacts[i]); + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); + m_global_contactcount++; + } + } + else + { + if (p2.PhysicsActorType == (int)ActorTypes.Prim && p1.PhysicsActorType == (int)ActorTypes.Prim) + { + // prim prim contact + int pj294950 = 0; + int movintYN = 0; + // prim terrain contact + if (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f) + { + movintYN = 1; + } + int material = ((OdePrim)p2).m_material; + //m_log.DebugFormat("Material: {0}", material); + m_materialContacts[material, movintYN].geom = contacts[i]; + _perloopContact.Add(contacts[i]); + + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); + m_global_contactcount++; + + } + + } + else + { + + int movintYN = 0; + // prim terrain contact + if (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f) + { + movintYN = 1; + } + int material = ((OdePrim)p2).m_material; + //m_log.DebugFormat("Material: {0}", material); + m_materialContacts[material, movintYN].geom = contacts[i]; + _perloopContact.Add(contacts[i]); + + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); + m_global_contactcount++; + + } + } } } //if (p2.PhysicsActorType == (int)ActorTypes.Prim) @@ -885,13 +1088,14 @@ namespace OpenSim.Region.Physics.OdePlugin } 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) @@ -913,28 +1117,46 @@ namespace OpenSim.Region.Physics.OdePlugin { // we're colliding with prim or avatar // check if we're moving - if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && - (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) + if ((p2.PhysicsActorType == (int)ActorTypes.Agent)) { - // Use the Movement prim contact - AvatarMovementprimContact.geom = contacts[i]; - _perloopContact.Add(contacts[i]); - if (m_global_contactcount < maxContactsbeforedeath) + if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) { - joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); - m_global_contactcount++; + // Use the Movement prim contact + AvatarMovementprimContact.geom = contacts[i]; + _perloopContact.Add(contacts[i]); + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); + m_global_contactcount++; + } + } + else + { + // Use the non movement contact + contact.geom = contacts[i]; + _perloopContact.Add(contacts[i]); + + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref contact); + m_global_contactcount++; + } } } - else + else if (p2.PhysicsActorType == (int)ActorTypes.Prim) { - // Use the non movement contact - contact.geom = contacts[i]; + //p1.PhysicsActorType + int material = ((OdePrim)p2).m_material; + + //m_log.DebugFormat("Material: {0}", material); + m_materialContacts[material, 0].geom = contacts[i]; _perloopContact.Add(contacts[i]); if (m_global_contactcount < maxContactsbeforedeath) { - joint = d.JointCreateContact(world, contactgroup, ref contact); + joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, 0]); m_global_contactcount++; + } } } -- cgit v1.1