From cb07ba0d68eeb57bae1cb60f387483ff720cc29d Mon Sep 17 00:00:00 2001
From: Teravus Ovares
Date: Sat, 10 Nov 2007 19:13:52 +0000
Subject: * Moves the Meshmerizer to a separate plugin * Experimental. Linux
Prebuild needs testing. * One more update after this to remove the ODEMeshing
directory....
---
.../Region/Physics/BulletXPlugin/BulletXPlugin.cs | 145 +++++++++++++++----
.../BulletXPlugin/TriangleIndexVertexArray.cs | 161 +++++++++++++++++++++
2 files changed, 275 insertions(+), 31 deletions(-)
create mode 100644 OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs
(limited to 'OpenSim/Region/Physics/BulletXPlugin')
diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
index c733adb..2db7a54 100644
--- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
+++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
@@ -64,6 +64,7 @@ using System;
using System.Collections.Generic;
using MonoXnaCompactMaths;
using OpenSim.Framework;
+using OpenSim.Framework.Console;
using OpenSim.Region.Physics.Manager;
using XnaDevRu.BulletX;
using XnaDevRu.BulletX.Dynamics;
@@ -74,15 +75,6 @@ using BoxShape=XnaDevRu.BulletX.BoxShape;
namespace OpenSim.Region.Physics.BulletXPlugin
{
- ///
- /// This class is only here for compilations reasons
- ///
- public class Mesh
- {
- public Mesh()
- {
- }
- }
///
/// BulletXConversions are called now BulletXMaths
@@ -268,6 +260,65 @@ namespace OpenSim.Region.Physics.BulletXPlugin
}
}
+
+ // Class to detect and debug collisions
+ // Mainly used for debugging purposes
+ class CollisionDispatcherLocal : CollisionDispatcher
+ {
+
+ BulletXScene relatedScene;
+
+ public CollisionDispatcherLocal(BulletXScene s)
+ : base()
+ {
+ relatedScene=s;
+ }
+
+ public override bool NeedsCollision(CollisionObject bodyA, CollisionObject bodyB)
+ {
+ RigidBody rb;
+ BulletXCharacter bxcA=null;
+ BulletXPrim bxpA = null;
+ Type t = bodyA.GetType();
+ if (t==typeof(RigidBody)) {
+ rb = (RigidBody)bodyA;
+ relatedScene._characters.TryGetValue(rb, out bxcA);
+ relatedScene._prims.TryGetValue(rb, out bxpA);
+ }
+ String nameA;
+ if (bxcA != null)
+ nameA = bxcA._name;
+ else if (bxpA != null)
+ nameA = bxpA._name;
+ else
+ nameA = "null";
+
+ BulletXCharacter bxcB = null;
+ BulletXPrim bxpB = null;
+ t = bodyB.GetType();
+ if (t == typeof(RigidBody))
+ {
+ rb = (RigidBody)bodyB;
+ relatedScene._characters.TryGetValue(rb, out bxcB);
+ relatedScene._prims.TryGetValue(rb, out bxpB);
+ }
+ String nameB;
+ if (bxcB != null)
+ nameB = bxcB._name;
+ else if (bxpB != null)
+ nameB = bxpB._name;
+ else
+ nameB = "null";
+
+ bool needsCollision=base.NeedsCollision(bodyA, bodyB);
+
+ MainLog.Instance.Debug("BulletX", "A collision was detected between {0} and {1} --> {2}", nameA, nameB, needsCollision);
+
+
+ return needsCollision;
+ }
+ }
+
///
/// PhysicsScene Class for BulletX
///
@@ -294,8 +345,11 @@ namespace OpenSim.Region.Physics.BulletXPlugin
private const int simulationSubSteps = 10;
//private float[] _heightmap;
private BulletXPlanet _simFlatPlanet;
- private List _characters = new List();
- private List _prims = new List();
+ internal Dictionary _characters = new Dictionary();
+ internal Dictionary _prims = new Dictionary();
+
+ public IMesher mesher;
+
public static float Gravity
{
@@ -334,7 +388,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
public BulletXScene()
{
- cDispatcher = new CollisionDispatcher();
+ cDispatcher = new CollisionDispatcherLocal(this);
Vector3 worldMinDim = new Vector3((float) minXY, (float) minXY, (float) minZ);
Vector3 worldMaxDim = new Vector3((float) maxXY, (float) maxXY, (float) maxZ);
opCache = new AxisSweep3(worldMinDim, worldMaxDim, maxHandles);
@@ -348,6 +402,12 @@ namespace OpenSim.Region.Physics.BulletXPlugin
//this._heightmap = new float[65536];
}
+ public override void Initialise(IMesher meshmerizer)
+ {
+ mesher = meshmerizer;
+ }
+
+
public override PhysicsActor AddAvatar(string avName, PhysicsVector position)
{
PhysicsVector pos = new PhysicsVector();
@@ -358,7 +418,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
lock (BulletXLock)
{
newAv = new BulletXCharacter(avName, this, pos);
- _characters.Add(newAv);
+ _characters.Add(newAv.RigidBody, newAv);
}
return newAv;
}
@@ -379,7 +439,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
((BulletXCharacter) actor).RigidBody.ActivationState = ActivationState.DisableSimulation;
AddForgottenRigidBody(((BulletXCharacter) actor).RigidBody);
}
- _characters.Remove((BulletXCharacter) actor);
+ _characters.Remove(((BulletXCharacter)actor).RigidBody);
}
GC.Collect();
}
@@ -405,7 +465,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
}
else
{
- Mesh mesh = null;
+ IMesh mesh = mesher.CreateMesh(primName, pbs, size);
result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical);
}
break;
@@ -419,13 +479,13 @@ namespace OpenSim.Region.Physics.BulletXPlugin
}
public PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, AxiomQuaternion rotation,
- Mesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
+ IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
{
BulletXPrim newPrim = null;
lock (BulletXLock)
{
newPrim = new BulletXPrim(name, this, position, size, rotation, mesh, pbs, isPhysical);
- _prims.Add(newPrim);
+ _prims.Add(newPrim.RigidBody, newPrim);
}
return newPrim;
}
@@ -446,7 +506,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
((BulletXPrim) prim).RigidBody.ActivationState = ActivationState.DisableSimulation;
AddForgottenRigidBody(((BulletXPrim) prim).RigidBody);
}
- _prims.Remove((BulletXPrim) prim);
+ _prims.Remove(((BulletXPrim) prim).RigidBody);
}
GC.Collect();
}
@@ -470,11 +530,11 @@ namespace OpenSim.Region.Physics.BulletXPlugin
private void MoveAllObjects(float timeStep)
{
- foreach (BulletXCharacter actor in _characters)
+ foreach (BulletXCharacter actor in _characters.Values)
{
actor.Move(timeStep);
}
- foreach (BulletXPrim prim in _prims)
+ foreach (BulletXPrim prim in _prims.Values)
{
}
}
@@ -482,14 +542,14 @@ namespace OpenSim.Region.Physics.BulletXPlugin
private void ValidateHeightForAll()
{
float _height;
- foreach (BulletXCharacter actor in _characters)
+ foreach (BulletXCharacter actor in _characters.Values)
{
//_height = HeightValue(actor.RigidBodyPosition);
_height = _simFlatPlanet.HeightValue(actor.RigidBodyPosition);
actor.ValidateHeight(_height);
//if (_simFlatPlanet.heightIsNotValid(actor.RigidBodyPosition, out _height)) actor.ValidateHeight(_height);
}
- foreach (BulletXPrim prim in _prims)
+ foreach (BulletXPrim prim in _prims.Values)
{
//_height = HeightValue(prim.RigidBodyPosition);
_height = _simFlatPlanet.HeightValue(prim.RigidBodyPosition);
@@ -510,11 +570,11 @@ namespace OpenSim.Region.Physics.BulletXPlugin
{
//UpdatePosition > UpdateKinetics.
//Not only position will be updated, also velocity cause acceleration.
- foreach (BulletXCharacter actor in _characters)
+ foreach (BulletXCharacter actor in _characters.Values)
{
actor.UpdateKinetics();
}
- foreach (BulletXPrim prim in _prims)
+ foreach (BulletXPrim prim in _prims.Values)
{
prim.UpdateKinetics();
}
@@ -646,9 +706,11 @@ namespace OpenSim.Region.Physics.BulletXPlugin
protected PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
protected RigidBody rigidBody;
private Boolean iscolliding = false;
+ internal string _name;
- public BulletXActor()
+ public BulletXActor(String name)
{
+ _name = name;
}
public override PhysicsVector Position
@@ -847,6 +909,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
}
public BulletXCharacter(String avName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity,
PhysicsVector size, PhysicsVector acceleration, AxiomQuaternion orientation)
+ : base(avName)
{
//This fields will be removed. They're temporal
float _sizeX = 0.5f;
@@ -1016,14 +1079,15 @@ namespace OpenSim.Region.Physics.BulletXPlugin
private bool m_lastUpdateSent = false;
public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector size,
- AxiomQuaternion rotation, Mesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
+ AxiomQuaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
: this(primName, parent_scene, pos, new PhysicsVector(), size, new PhysicsVector(), rotation, mesh, pbs, isPhysical)
{
}
public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity,
PhysicsVector size,
- PhysicsVector acceleration, AxiomQuaternion rotation, Mesh mesh, PrimitiveBaseShape pbs,
+ PhysicsVector acceleration, AxiomQuaternion rotation, IMesh mesh, PrimitiveBaseShape pbs,
bool isPhysical)
+ : base(primName)
{
if ((size.X == 0) || (size.Y == 0) || (size.Z == 0)) throw new Exception("Size 0");
if (rotation.Norm == 0f) rotation = AxiomQuaternion.Identity;
@@ -1037,7 +1101,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
_parent_scene = parent_scene;
- CreateRigidBody(parent_scene, pos, size);
+ CreateRigidBody(parent_scene, mesh, pos, size);
}
public override PhysicsVector Position
@@ -1191,7 +1255,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
}
#region Methods for updating values of RigidBody
- internal protected void CreateRigidBody(BulletXScene parent_scene, PhysicsVector pos, PhysicsVector size)
+ internal protected void CreateRigidBody(BulletXScene parent_scene, IMesh mesh, PhysicsVector pos, PhysicsVector size)
{
//For RigidBody Constructor. The next values might change
float _linearDamping = 0.0f;
@@ -1204,7 +1268,26 @@ namespace OpenSim.Region.Physics.BulletXPlugin
{
_startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);
//For now all prims are boxes
- CollisionShape _collisionShape = new XnaDevRu.BulletX.BoxShape(BulletXMaths.PhysicsVectorToXnaVector3(size) / 2.0f);
+ CollisionShape _collisionShape;
+ if (mesh == null)
+ {
+ _collisionShape = new XnaDevRu.BulletX.BoxShape(BulletXMaths.PhysicsVectorToXnaVector3(size) / 2.0f);
+ } else {
+ int iVertexCount = mesh.getVertexList().Count;
+ int[] indices = mesh.getIndexListAsInt();
+ Vector3[] v3Vertices = new Vector3[iVertexCount];
+ for (int i = 0; i < iVertexCount; i++)
+ {
+ PhysicsVector v=mesh.getVertexList()[i];
+ if (v != null) // Note, null has special meaning. See meshing code for details
+ v3Vertices[i] = BulletXMaths.PhysicsVectorToXnaVector3(v);
+ else
+ v3Vertices[i] = MonoXnaCompactMaths.Vector3.Zero;
+ }
+ TriangleIndexVertexArray triMesh = new TriangleIndexVertexArray(indices, v3Vertices);
+
+ _collisionShape = new XnaDevRu.BulletX.TriangleMeshShape(triMesh);
+ }
DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
Vector3 _localInertia = new Vector3();
if (_physical) _collisionShape.CalculateLocalInertia(Mass, out _localInertia); //Always when mass > 0
@@ -1231,7 +1314,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
rigidBody.ActivationState = ActivationState.DisableSimulation;
this._parent_scene.AddForgottenRigidBody(rigidBody);
}
- CreateRigidBody(this._parent_scene, this._position, size);
+ CreateRigidBody(this._parent_scene, null, this._position, size); // Note, null for the meshing definitely is wrong. It's here for the moment to apease the compiler
if (_physical) Speed();//Static objects don't have linear velocity
ReOrient();
GC.Collect();
diff --git a/OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs b/OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs
new file mode 100644
index 0000000..fb30296
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs
@@ -0,0 +1,161 @@
+/*
+ Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
+ Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+
+ This file contains a class TriangleIndexVertexArray. I tried using the class with the same name
+ from the BulletX implementation and found it unusable for the purpose of using triangle meshes
+ within BulletX as the implementation was painfully incomplete.
+ The attempt to derive from the original class failed as viable members were hidden.
+ Fiddling around with BulletX itself was not my intention.
+ So I copied the class to the BulletX-plugin and modified it.
+ If you want to fiddle around with it it's up to you to move all this to BulletX.
+ If someone someday implements the missing functionality in BulletX, feel free to remove this class.
+ It's just an ugly hack.
+
+ */
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MonoXnaCompactMaths;
+
+namespace OpenSim.Region.Physics.BulletXPlugin
+{
+ ///
+ /// IndexedMesh indexes into existing vertex and index arrays, in a similar way OpenGL glDrawElements
+ /// instead of the number of indices, we pass the number of triangles
+ ///
+ public struct IndexedMesh
+ {
+ private int _numTriangles;
+ private int[] _triangleIndexBase;
+ private int _triangleIndexStride;
+ private int _numVertices;
+ private Vector3[] _vertexBase;
+ private int _vertexStride;
+
+ public IndexedMesh(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, Vector3[] vertexBase, int vertexStride)
+ {
+ _numTriangles = numTriangleIndices;
+ _triangleIndexBase = triangleIndexBase;
+ _triangleIndexStride = triangleIndexStride;
+ _vertexBase = vertexBase;
+ _numVertices = numVertices;
+ _vertexStride = vertexStride;
+ }
+
+ public IndexedMesh(int[] triangleIndexBase, Vector3[] vertexBase)
+ {
+ _numTriangles = triangleIndexBase.Length;
+ _triangleIndexBase = triangleIndexBase;
+ _triangleIndexStride = 32;
+ _vertexBase = vertexBase;
+ _numVertices = vertexBase.Length;
+ _vertexStride = 24;
+ }
+
+ public int TriangleCount { get { return _numTriangles; } set { _numTriangles = value; } }
+ public int[] TriangleIndexBase { get { return _triangleIndexBase; } set { _triangleIndexBase = value; } }
+ public int TriangleIndexStride { get { return _triangleIndexStride; } set { _triangleIndexStride = value; } }
+ public int VertexCount { get { return _numVertices; } set { _numVertices = value; } }
+ public Vector3[] VertexBase { get { return _vertexBase; } set { _vertexBase = value; } }
+ public int VertexStride { get { return _vertexStride; } set { _vertexStride = value; } }
+ }
+
+ ///
+ /// TriangleIndexVertexArray allows to use multiple meshes, by indexing into existing triangle/index arrays.
+ /// Additional meshes can be added using addIndexedMesh
+ ///
+ public class TriangleIndexVertexArray : XnaDevRu.BulletX.StridingMeshInterface
+ {
+ List _indexedMeshes = new List();
+
+ public TriangleIndexVertexArray() { }
+
+ public TriangleIndexVertexArray(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, Vector3[] vertexBase, int vertexStride)
+ {
+ IndexedMesh mesh = new IndexedMesh();
+ mesh.TriangleCount = numTriangleIndices;
+ mesh.TriangleIndexBase = triangleIndexBase;
+ mesh.TriangleIndexStride = triangleIndexStride;
+ mesh.VertexBase = vertexBase;
+ mesh.VertexCount = numVertices;
+ mesh.VertexStride = vertexStride;
+
+ AddIndexedMesh(mesh);
+ }
+
+ public TriangleIndexVertexArray(int[] triangleIndexBase, Vector3[] vertexBase)
+ : this(triangleIndexBase.Length, triangleIndexBase, 32, vertexBase.Length, vertexBase, 24) { }
+
+ public void AddIndexedMesh(IndexedMesh indexedMesh)
+ {
+ _indexedMeshes.Add(indexedMesh);
+ }
+
+ public override void GetLockedVertexIndexBase(out List verts, out List indicies, out int numfaces, int subpart)
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+
+ public override void GetLockedReadOnlyVertexIndexBase(out List verts, out List indicies, out int numfaces, int subpart)
+ {
+ IndexedMesh m = _indexedMeshes[0];
+ Vector3[] vertexBase = m.VertexBase;
+ verts = new List();
+ foreach (Vector3 v in vertexBase)
+ {
+ verts.Add(v);
+ }
+ int[] indexBase = m.TriangleIndexBase;
+ indicies = new List();
+ foreach (int i in indexBase)
+ {
+ indicies.Add(i);
+ }
+ numfaces = vertexBase.GetLength(0);
+ }
+
+ public override void UnLockVertexBase(int subpart)
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+
+ public override void UnLockReadOnlyVertexBase(int subpart)
+ {
+ }
+
+ public override int SubPartsCount()
+ {
+ return _indexedMeshes.Count;
+ }
+
+ public override void PreallocateVertices(int numverts)
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+
+ public override void PreallocateIndices(int numindices)
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+ }
+}
--
cgit v1.1