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