diff --git a/OpenSim/Region/Application/OpenSimMain.cs b/OpenSim/Region/Application/OpenSimMain.cs
index 684a9a8712..42f1b941de 100644
--- a/OpenSim/Region/Application/OpenSimMain.cs
+++ b/OpenSim/Region/Application/OpenSimMain.cs
@@ -54,6 +54,7 @@ namespace OpenSim
private const string DEFAULT_PRIM_BACKUP_FILENAME = "prim-backup.xml";
public string m_physicsEngine;
+ public string m_meshEngineName;
public string m_scriptEngine;
public bool m_sandbox;
public bool user_accounts;
@@ -210,6 +211,7 @@ namespace OpenSim
{
m_sandbox = !startupConfig.GetBoolean("gridmode", false);
m_physicsEngine = startupConfig.GetString("physics", "basicphysics");
+ m_meshEngineName = startupConfig.GetString("meshing", "Meshmerizer");
m_verbose = startupConfig.GetBoolean("verbose", true);
m_permissions = startupConfig.GetBoolean("serverside_object_permissions", false);
@@ -404,7 +406,7 @@ namespace OpenSim
protected override PhysicsScene GetPhysicsScene()
{
- return GetPhysicsScene(m_physicsEngine);
+ return GetPhysicsScene(m_physicsEngine, m_meshEngineName);
}
private class SimStatusHandler : IStreamedRequestHandler
@@ -767,4 +769,4 @@ namespace OpenSim
#endregion
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
index 6071dcd188..b0e641970f 100644
--- a/OpenSim/Region/ClientStack/RegionApplicationBase.cs
+++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
@@ -29,6 +29,7 @@ using System;
using System.Collections.Generic;
using System.Net;
using libsecondlife;
+using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
using OpenSim.Framework.Communications.Cache;
@@ -89,12 +90,12 @@ namespace OpenSim.Region.ClientStack
protected abstract PhysicsScene GetPhysicsScene();
protected abstract StorageManager CreateStorageManager(RegionInfo regionInfo);
- protected PhysicsScene GetPhysicsScene(string engine)
+ protected PhysicsScene GetPhysicsScene(string engine, string meshEngine)
{
PhysicsPluginManager physicsPluginManager;
physicsPluginManager = new PhysicsPluginManager();
physicsPluginManager.LoadPlugins();
- return physicsPluginManager.GetPhysicsScene(engine);
+ return physicsPluginManager.GetPhysicsScene(engine, meshEngine);
}
protected Scene SetupScene(RegionInfo regionInfo, out UDPServer udpServer)
@@ -150,4 +151,4 @@ namespace OpenSim.Region.ClientStack
protected abstract Scene CreateScene(RegionInfo regionInfo, StorageManager storageManager,
AgentCircuitManager circuitManager);
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/Examples/SimpleApp/Program.cs b/OpenSim/Region/Examples/SimpleApp/Program.cs
index 875bc4c601..49fae93829 100644
--- a/OpenSim/Region/Examples/SimpleApp/Program.cs
+++ b/OpenSim/Region/Examples/SimpleApp/Program.cs
@@ -182,7 +182,7 @@ namespace SimpleApp
protected override PhysicsScene GetPhysicsScene()
{
- return GetPhysicsScene("basicphysics");
+ return GetPhysicsScene("basicphysics", "Meshmerizer");
}
#region conscmd_callback Members
@@ -206,4 +206,4 @@ namespace SimpleApp
app.Run();
}
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
index 63773922fc..1d1c14f991 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
@@ -70,6 +70,11 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
{
}
+ public override void Initialise(IMesher meshmerizer)
+ {
+ // Does nothing right now
+ }
+
public override PhysicsActor AddAvatar(string avName, PhysicsVector position)
{
BasicActor act = new BasicActor();
@@ -274,4 +279,4 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
{
}
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
index c733adbeab..2db7a5487a 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 0000000000..fb302966d6
--- /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.");
+ }
+ }
+}
diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs
new file mode 100644
index 0000000000..037616c0d4
--- /dev/null
+++ b/OpenSim/Region/Physics/Manager/IMesher.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using OpenSim.Framework;
+
+namespace OpenSim.Region.Physics.Manager
+{
+ public interface IMesher
+ {
+ IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size);
+ }
+
+ public interface IVertex {
+ }
+
+ public interface IMesh
+ {
+ List getVertexList();
+ int[] getIndexListAsInt();
+ int[] getIndexListAsIntLocked();
+ float[] getVertexListAsFloatLocked();
+
+
+ }
+}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
index 09ebf29a32..47c8ae07a8 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
using System.IO;
using System.Reflection;
using OpenSim.Framework.Console;
+using Nini.Config;
namespace OpenSim.Region.Physics.Manager
{
@@ -38,28 +39,50 @@ namespace OpenSim.Region.Physics.Manager
///
public class PhysicsPluginManager
{
- private Dictionary _plugins = new Dictionary();
+ private Dictionary _PhysPlugins = new Dictionary();
+ private Dictionary _MeshPlugins = new Dictionary();
public PhysicsPluginManager()
{
}
- public PhysicsScene GetPhysicsScene(string engineName)
+ public PhysicsScene GetPhysicsScene(string physEngineName, string meshEngineName)
{
- if (String.IsNullOrEmpty(engineName))
+
+ if (String.IsNullOrEmpty(physEngineName))
{
return PhysicsScene.Null;
}
- if (_plugins.ContainsKey(engineName))
+ if (String.IsNullOrEmpty(meshEngineName))
{
- MainLog.Instance.Verbose("PHYSICS", "creating " + engineName);
- return _plugins[engineName].GetScene();
+ return PhysicsScene.Null;
+ }
+
+
+ IMesher meshEngine = null;
+ if (_MeshPlugins.ContainsKey(meshEngineName))
+ {
+ MainLog.Instance.Verbose("PHYSICS", "creating meshing engine " + meshEngineName);
+ meshEngine = _MeshPlugins[meshEngineName].GetMesher();
}
else
{
- MainLog.Instance.Warn("PHYSICS", "couldn't find physicsEngine: {0}", engineName);
- throw new ArgumentException(String.Format("couldn't find physicsEngine: {0}", engineName));
+ MainLog.Instance.Warn("PHYSICS", "couldn't find meshingEngine: {0}", meshEngineName);
+ throw new ArgumentException(String.Format("couldn't find meshingEngine: {0}", meshEngineName));
+ }
+
+ if (_PhysPlugins.ContainsKey(physEngineName))
+ {
+ MainLog.Instance.Verbose("PHYSICS", "creating " + physEngineName);
+ PhysicsScene result = _PhysPlugins[physEngineName].GetScene();
+ result.Initialise(meshEngine);
+ return result;
+ }
+ else
+ {
+ MainLog.Instance.Warn("PHYSICS", "couldn't find physicsEngine: {0}", physEngineName);
+ throw new ArgumentException(String.Format("couldn't find physicsEngine: {0}", physEngineName));
}
}
@@ -85,18 +108,29 @@ namespace OpenSim.Region.Physics.Manager
{
if (!pluginType.IsAbstract)
{
- Type typeInterface = pluginType.GetInterface("IPhysicsPlugin", true);
+ Type physTypeInterface = pluginType.GetInterface("IPhysicsPlugin", true);
- if (typeInterface != null)
+ if (physTypeInterface != null)
{
IPhysicsPlugin plug =
(IPhysicsPlugin) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
plug.Init();
- _plugins.Add(plug.GetName(), plug);
+ _PhysPlugins.Add(plug.GetName(), plug);
MainLog.Instance.Verbose("PHYSICS", "Added physics engine: " + plug.GetName());
}
- typeInterface = null;
+ Type meshTypeInterface = pluginType.GetInterface("IMeshingPlugin", true);
+
+ if (meshTypeInterface != null)
+ {
+ IMeshingPlugin plug =
+ (IMeshingPlugin)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
+ _MeshPlugins.Add(plug.GetName(), plug);
+ MainLog.Instance.Verbose("PHYSICS", "Added meshing engine: " + plug.GetName());
+ }
+
+ physTypeInterface = null;
+ meshTypeInterface = null;
}
}
}
@@ -127,4 +161,11 @@ namespace OpenSim.Region.Physics.Manager
string GetName();
void Dispose();
}
-}
\ No newline at end of file
+
+ public interface IMeshingPlugin
+ {
+ string GetName();
+ IMesher GetMesher();
+ }
+
+}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index 13591eabf7..6f19e72443 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -28,6 +28,7 @@
using Axiom.Math;
using OpenSim.Framework;
using OpenSim.Framework.Console;
+using OpenSim.Region.Physics.Manager;
namespace OpenSim.Region.Physics.Manager
{
@@ -38,6 +39,8 @@ namespace OpenSim.Region.Physics.Manager
get { return new NullPhysicsScene(); }
}
+ public abstract void Initialise(IMesher meshmerizer);
+
public abstract PhysicsActor AddAvatar(string avName, PhysicsVector position);
public abstract void RemoveAvatar(PhysicsActor actor);
@@ -63,6 +66,12 @@ namespace OpenSim.Region.Physics.Manager
{
private static int m_workIndicator;
+
+ public override void Initialise(IMesher meshmerizer)
+ {
+ // Does nothing right now
+ }
+
public override PhysicsActor AddAvatar(string avName, PhysicsVector position)
{
MainLog.Instance.Verbose("NullPhysicsScene : AddAvatar({0})", position);
@@ -123,4 +132,4 @@ namespace OpenSim.Region.Physics.Manager
}
}
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/Physics/Meshing/Extruder.cs b/OpenSim/Region/Physics/Meshing/Extruder.cs
new file mode 100644
index 0000000000..63d727ff21
--- /dev/null
+++ b/OpenSim/Region/Physics/Meshing/Extruder.cs
@@ -0,0 +1,83 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OpenSim.Region.Physics.Meshing
+{
+ class Extruder
+ {
+ public float startParameter;
+ public float stopParameter;
+ public Manager.PhysicsVector size;
+
+ public Mesh Extrude(Mesh m)
+ {
+ // Currently only works for iSteps=1;
+ Mesh result = new Mesh();
+
+ Mesh workingPlus = m.Clone();
+ Mesh workingMinus = m.Clone();
+
+ foreach (Vertex v in workingPlus.vertices)
+ {
+ if (v == null)
+ continue;
+
+ v.Z = +.5f;
+ v.X *= size.X;
+ v.Y *= size.Y;
+ v.Z *= size.Z;
+ }
+
+ foreach (Vertex v in workingMinus.vertices)
+ {
+ if (v == null)
+ continue;
+
+ v.Z = -.5f;
+ v.X *= size.X;
+ v.Y *= size.Y;
+ v.Z *= size.Z;
+ }
+
+ foreach (Triangle t in workingMinus.triangles)
+ {
+ t.invertNormal();
+ }
+
+ result.Append(workingMinus);
+ result.Append(workingPlus);
+
+ int iLastNull = 0;
+ for (int i = 0; i < workingPlus.vertices.Count; i++)
+ {
+ int iNext = (i + 1);
+
+ if (workingPlus.vertices[i] == null) // Can't make a simplex here
+ {
+ iLastNull = i+1;
+ continue;
+ }
+
+ if (i == workingPlus.vertices.Count-1) // End of list
+ {
+ iNext = iLastNull;
+ }
+
+ if (workingPlus.vertices[iNext] == null) // Null means wrap to begin of last segment
+ {
+ iNext = iLastNull;
+ }
+
+ Triangle tSide;
+ tSide = new Triangle(workingPlus.vertices[i], workingMinus.vertices[i], workingPlus.vertices[iNext]);
+ result.Add(tSide);
+
+ tSide = new Triangle(workingPlus.vertices[iNext], workingMinus.vertices[i], workingMinus.vertices[iNext]);
+ result.Add(tSide);
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/OpenSim/Region/Physics/Meshing/HelperTypes.cs b/OpenSim/Region/Physics/Meshing/HelperTypes.cs
new file mode 100644
index 0000000000..9e7582672c
--- /dev/null
+++ b/OpenSim/Region/Physics/Meshing/HelperTypes.cs
@@ -0,0 +1,306 @@
+/*
+* Copyright (c) Contributors, http://opensimulator.org/
+* See CONTRIBUTORS.TXT for a full list of copyright holders.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the OpenSim Project nor the
+* names of its contributors may be used to endorse or promote products
+* derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using OpenSim.Framework.Console;
+using OpenSim.Region.Physics.Manager;
+
+using OpenSim.Region.Physics.Meshing;
+
+public class Vertex : PhysicsVector, IComparable
+{
+ public Vertex(float x, float y, float z)
+ : base(x, y, z)
+ {
+ }
+
+ public Vertex(PhysicsVector v)
+ : base(v.X, v.Y, v.Z)
+ {
+ }
+
+ public Vertex Clone()
+ {
+ return new Vertex(X, Y, Z);
+ }
+
+ public static Vertex FromAngle(double angle)
+ {
+ return new Vertex((float)Math.Cos(angle), (float)Math.Sin(angle), 0.0f);
+ }
+
+
+ public virtual bool Equals(Vertex v, float tolerance)
+ {
+ PhysicsVector diff = this - v;
+ float d = diff.length();
+ if (d < tolerance)
+ return true;
+
+ return false;
+ }
+
+
+ public int CompareTo(Vertex other)
+ {
+ if (X < other.X)
+ return -1;
+
+ if (X > other.X)
+ return 1;
+
+ if (Y < other.Y)
+ return -1;
+
+ if (Y > other.Y)
+ return 1;
+
+ if (Z < other.Z)
+ return -1;
+
+ if (Z > other.Z)
+ return 1;
+
+ return 0;
+ }
+
+ public static bool operator >(Vertex me, Vertex other)
+ {
+ return me.CompareTo(other) > 0;
+ }
+
+ public static bool operator <(Vertex me, Vertex other)
+ {
+ return me.CompareTo(other) < 0;
+ }
+ public String ToRaw()
+ {
+ // Why this stuff with the number formatter?
+ // Well, the raw format uses the english/US notation of numbers
+ // where the "," separates groups of 1000 while the "." marks the border between 1 and 10E-1.
+ // The german notation uses these characters exactly vice versa!
+ // The Float.ToString() routine is a localized one, giving different results depending on the country
+ // settings your machine works with. Unusable for a machine readable file format :-(
+ NumberFormatInfo nfi = new NumberFormatInfo();
+ nfi.NumberDecimalSeparator = ".";
+ nfi.NumberDecimalDigits = 3;
+
+ String s1 = X.ToString("N2", nfi) + " " + Y.ToString("N2", nfi) + " " + Z.ToString("N2", nfi);
+
+ return s1;
+ }
+
+}
+
+public class Triangle
+{
+ public Vertex v1;
+ public Vertex v2;
+ public Vertex v3;
+
+ private float radius_square;
+ private float cx;
+ private float cy;
+
+ public Triangle(Vertex _v1, Vertex _v2, Vertex _v3)
+ {
+ v1 = _v1;
+ v2 = _v2;
+ v3 = _v3;
+
+ CalcCircle();
+ }
+
+ public bool isInCircle(float x, float y)
+ {
+ float dx, dy;
+ float dd;
+
+ dx = x - cx;
+ dy = y - cy;
+
+ dd = dx*dx + dy*dy;
+ if (dd < radius_square)
+ return true;
+ else
+ return false;
+ }
+
+ public bool isDegraded()
+ {
+ // This means, the vertices of this triangle are somewhat strange.
+ // They either line up or at least two of them are identical
+ return (radius_square == 0.0);
+ }
+
+ private void CalcCircle()
+ {
+ // Calculate the center and the radius of a circle given by three points p1, p2, p3
+ // It is assumed, that the triangles vertices are already set correctly
+ double p1x, p2x, p1y, p2y, p3x, p3y;
+
+ // Deviation of this routine:
+ // A circle has the general equation (M-p)^2=r^2, where M and p are vectors
+ // this gives us three equations f(p)=r^2, each for one point p1, p2, p3
+ // putting respectively two equations together gives two equations
+ // f(p1)=f(p2) and f(p1)=f(p3)
+ // bringing all constant terms to one side brings them to the form
+ // M*v1=c1 resp.M*v2=c2 where v1=(p1-p2) and v2=(p1-p3) (still vectors)
+ // and c1, c2 are scalars (Naming conventions like the variables below)
+ // Now using the equations that are formed by the components of the vectors
+ // and isolate Mx lets you make one equation that only holds My
+ // The rest is straight forward and eaasy :-)
+ //
+
+ /* helping variables for temporary results */
+ double c1, c2;
+ double v1x, v1y, v2x, v2y;
+
+ double z, n;
+
+ double rx, ry;
+
+ // Readout the three points, the triangle consists of
+ p1x = v1.X;
+ p1y = v1.Y;
+
+ p2x = v2.X;
+ p2y = v2.Y;
+
+ p3x = v3.X;
+ p3y = v3.Y;
+
+ /* calc helping values first */
+ c1 = (p1x*p1x + p1y*p1y - p2x*p2x - p2y*p2y)/2;
+ c2 = (p1x*p1x + p1y*p1y - p3x*p3x - p3y*p3y)/2;
+
+ v1x = p1x - p2x;
+ v1y = p1y - p2y;
+
+ v2x = p1x - p3x;
+ v2y = p1y - p3y;
+
+ z = (c1*v2x - c2*v1x);
+ n = (v1y*v2x - v2y*v1x);
+
+ if (n == 0.0) // This is no triangle, i.e there are (at least) two points at the same location
+ {
+ radius_square = 0.0f;
+ return;
+ }
+
+ cy = (float) (z/n);
+
+ if (v2x != 0.0)
+ {
+ cx = (float) ((c2 - v2y*cy)/v2x);
+ }
+ else if (v1x != 0.0)
+ {
+ cx = (float) ((c1 - v1y*cy)/v1x);
+ }
+ else
+ {
+ Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */
+ }
+
+ rx = (p1x - cx);
+ ry = (p1y - cy);
+
+ radius_square = (float) (rx*rx + ry*ry);
+ }
+
+ public List GetSimplices()
+ {
+ List result = new List();
+ Simplex s1 = new Simplex(v1, v2);
+ Simplex s2 = new Simplex(v2, v3);
+ Simplex s3 = new Simplex(v3, v1);
+
+ result.Add(s1);
+ result.Add(s2);
+ result.Add(s3);
+
+ return result;
+ }
+
+ public override String ToString()
+ {
+ NumberFormatInfo nfi = new NumberFormatInfo();
+ nfi.CurrencyDecimalDigits = 2;
+ nfi.CurrencyDecimalSeparator = ".";
+
+ String s1 = "<" + v1.X.ToString(nfi) + "," + v1.Y.ToString(nfi) + "," + v1.Z.ToString(nfi) + ">";
+ String s2 = "<" + v2.X.ToString(nfi) + "," + v2.Y.ToString(nfi) + "," + v2.Z.ToString(nfi) + ">";
+ String s3 = "<" + v3.X.ToString(nfi) + "," + v3.Y.ToString(nfi) + "," + v3.Z.ToString(nfi) + ">";
+
+ return s1 + ";" + s2 + ";" + s3;
+ }
+
+ public PhysicsVector getNormal()
+ {
+ // Vertices
+
+ // Vectors for edges
+ PhysicsVector e1;
+ PhysicsVector e2;
+
+ e1 = new PhysicsVector(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
+ e2 = new PhysicsVector(v1.X - v3.X, v1.Y - v3.Y, v1.Z - v3.Z);
+
+ // Cross product for normal
+ PhysicsVector n = PhysicsVector.cross(e1, e2);
+
+ // Length
+ float l = n.length();
+
+ // Normalized "normal"
+ n = n / l;
+
+ return n;
+ }
+
+ public void invertNormal()
+ {
+ Vertex vt;
+ vt = v1;
+ v1 = v2;
+ v2 = vt;
+ }
+
+ // Dumps a triangle in the "raw faces" format, blender can import. This is for visualisation and
+ // debugging purposes
+ public String ToStringRaw()
+ {
+ String output = v1.ToRaw() + " " + v2.ToRaw() + " " +v3.ToRaw();
+ return output;
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/Region/Physics/Meshing/Mesh.cs b/OpenSim/Region/Physics/Meshing/Mesh.cs
new file mode 100644
index 0000000000..fd4ce4e1d2
--- /dev/null
+++ b/OpenSim/Region/Physics/Meshing/Mesh.cs
@@ -0,0 +1,213 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Text;
+
+using System.Runtime.InteropServices;
+
+
+using OpenSim.Region.Physics.Manager;
+
+namespace OpenSim.Region.Physics.Meshing
+{
+ public class Mesh : IMesh
+ {
+ public List vertices;
+ public List triangles;
+
+ public float[] normals;
+
+ public Mesh()
+ {
+ vertices = new List();
+ triangles = new List();
+ }
+
+ public Mesh Clone()
+ {
+ Mesh result = new Mesh();
+
+ foreach (Vertex v in vertices)
+ {
+ if (v == null)
+ result.vertices.Add(null);
+ else
+ result.vertices.Add(v.Clone());
+ }
+
+ foreach (Triangle t in triangles)
+ {
+ int iV1, iV2, iV3;
+ iV1 = this.vertices.IndexOf(t.v1);
+ iV2 = this.vertices.IndexOf(t.v2);
+ iV3 = this.vertices.IndexOf(t.v3);
+
+ Triangle newT = new Triangle(result.vertices[iV1], result.vertices[iV2], result.vertices[iV3]);
+ result.Add(newT);
+ }
+
+ return result;
+ }
+
+
+
+ public void Add(Triangle triangle)
+ {
+ int i;
+ i = vertices.IndexOf(triangle.v1);
+ if (i < 0)
+ throw new ArgumentException("Vertex v1 not known to mesh");
+ i = vertices.IndexOf(triangle.v2);
+ if (i < 0)
+ throw new ArgumentException("Vertex v2 not known to mesh");
+ i = vertices.IndexOf(triangle.v3);
+ if (i < 0)
+ throw new ArgumentException("Vertex v3 not known to mesh");
+
+ triangles.Add(triangle);
+ }
+
+ public void Add(Vertex v)
+ {
+ vertices.Add(v);
+ }
+
+ public void Remove(Vertex v)
+ {
+ int i;
+
+ // First, remove all triangles that are build on v
+ for (i = 0; i < triangles.Count; i++)
+ {
+ Triangle t = triangles[i];
+ if (t.v1 == v || t.v2 == v || t.v3 == v)
+ {
+ triangles.RemoveAt(i);
+ i--;
+ }
+ }
+
+ // Second remove v itself
+ vertices.Remove(v);
+ }
+
+ public void RemoveTrianglesOutside(SimpleHull hull)
+ {
+ int i;
+
+ for (i = 0; i < triangles.Count; i++)
+ {
+ Triangle t = triangles[i];
+ Vertex v1 = t.v1;
+ Vertex v2 = t.v2;
+ Vertex v3 = t.v3;
+ PhysicsVector m = v1 + v2 + v3;
+ m /= 3.0f;
+ if (!hull.IsPointIn(new Vertex(m)))
+ {
+ triangles.RemoveAt(i);
+ i--;
+ }
+ }
+ }
+
+
+ public void Add(List lv)
+ {
+ foreach (Vertex v in lv)
+ {
+ vertices.Add(v);
+ }
+ }
+
+ public List getVertexList()
+ {
+ List result = new List();
+ foreach (Vertex v in vertices)
+ {
+ result.Add(v);
+ }
+ return result;
+ }
+
+ public float[] getVertexListAsFloatLocked()
+ {
+ float[] result = new float[vertices.Count * 3];
+ for (int i = 0; i < vertices.Count; i++)
+ {
+ Vertex v = vertices[i];
+ if (v == null)
+ continue;
+ result[3 * i + 0] = v.X;
+ result[3 * i + 1] = v.Y;
+ result[3 * i + 2] = v.Z;
+ }
+ GCHandle.Alloc(result, GCHandleType.Pinned);
+ return result;
+ }
+
+ public int[] getIndexListAsInt()
+ {
+ int[] result = new int[triangles.Count * 3];
+ for (int i = 0; i < triangles.Count; i++)
+ {
+ Triangle t = triangles[i];
+ result[3 * i + 0] = vertices.IndexOf(t.v1);
+ result[3 * i + 1] = vertices.IndexOf(t.v2);
+ result[3 * i + 2] = vertices.IndexOf(t.v3);
+ }
+ return result;
+ }
+
+ public int[] getIndexListAsIntLocked()
+ {
+ int[] result = getIndexListAsInt();
+ GCHandle.Alloc(result, GCHandleType.Pinned);
+ return result;
+ }
+
+
+ public void Append(Mesh newMesh)
+ {
+ foreach (Vertex v in newMesh.vertices)
+ vertices.Add(v);
+
+ foreach (Triangle t in newMesh.triangles)
+ Add(t);
+
+ }
+
+ // Do a linear transformation of mesh.
+ public void TransformLinear(float[,] matrix, float[] offset)
+ {
+ foreach (Vertex v in vertices)
+ {
+ if (v == null)
+ continue;
+ float x, y, z;
+ x = v.X * matrix[0, 0] + v.Y * matrix[1, 0] + v.Z * matrix[2, 0];
+ y = v.X * matrix[0, 1] + v.Y * matrix[1, 1] + v.Z * matrix[2, 1];
+ z = v.X * matrix[0, 2] + v.Y * matrix[1, 2] + v.Z * matrix[2, 2];
+ v.X = x + offset[0];
+ v.Y = y + offset[1];
+ v.Z = z + offset[2];
+ }
+ }
+
+ public void DumpRaw(String path, String name, String title)
+ {
+ if (path == null)
+ return;
+ String fileName = name + "_" + title + ".raw";
+ String completePath = Path.Combine(path, fileName);
+ StreamWriter sw = new StreamWriter(completePath);
+ foreach (Triangle t in triangles)
+ {
+ String s = t.ToStringRaw();
+ sw.WriteLine(s);
+ }
+ sw.Close();
+ }
+ }
+
+}
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
new file mode 100644
index 0000000000..da4ee580a7
--- /dev/null
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -0,0 +1,393 @@
+/*
+* Copyright (c) Contributors, http://opensimulator.org/
+* See CONTRIBUTORS.TXT for a full list of copyright holders.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the OpenSim Project nor the
+* names of its contributors may be used to endorse or promote products
+* derived from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
+using System;
+using System.IO;
+using System.Globalization;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using OpenSim.Framework;
+using OpenSim.Framework.Console;
+using OpenSim.Region.Physics.Manager;
+
+namespace OpenSim.Region.Physics.Meshing
+{
+
+ public class MeshmerizerPlugin : IMeshingPlugin
+ {
+ public MeshmerizerPlugin()
+ {
+ }
+
+ public string GetName()
+ {
+ return "Meshmerizer";
+ }
+
+ public IMesher GetMesher()
+ {
+ return new Meshmerizer();
+ }
+ }
+
+ public class Meshmerizer : IMesher
+ {
+ // Setting baseDir to a path will enable the dumping of raw files
+ // raw files can be imported by blender so a visual inspection of the results can be done
+ // const string baseDir = "rawFiles";
+ const string baseDir = null;
+
+ static void IntersectionParameterPD(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu)
+ {
+ // p1, p2, points on the straight
+ // r1, r2, directional vectors of the straight. Not necessarily of length 1!
+ // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points,
+ // thus allowing to decide whether an intersection is between two points
+
+ float r1x = r1.X;
+ float r1y = r1.Y;
+ float r2x = r2.X;
+ float r2y = r2.Y;
+
+ float denom = r1y*r2x - r1x*r2y;
+
+ if (denom == 0.0)
+ {
+ lambda = Single.NaN;
+ mu = Single.NaN;
+ return;
+ }
+
+ float p1x = p1.X;
+ float p1y = p1.Y;
+ float p2x = p2.X;
+ float p2y = p2.Y;
+ lambda = (-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x) / denom;
+ mu = (-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x) / denom;
+
+ }
+
+ private static List FindInfluencedTriangles(List triangles, Vertex v)
+ {
+ List influenced = new List();
+ foreach (Triangle t in triangles)
+ {
+ if (t.isInCircle(v.X, v.Y))
+ {
+ influenced.Add(t);
+ }
+ }
+ return influenced;
+ }
+
+
+ private static void InsertVertices(List vertices, int usedForSeed, List triangles)
+ {
+ // This is a variant of the delaunay algorithm
+ // each time a new vertex is inserted, all triangles that are influenced by it are deleted
+ // and replaced by new ones including the new vertex
+ // It is not very time efficient but easy to implement.
+
+ int iCurrentVertex;
+ int iMaxVertex = vertices.Count;
+ for (iCurrentVertex = usedForSeed; iCurrentVertex < iMaxVertex; iCurrentVertex++)
+ {
+ // Background: A triangle mesh fulfills the delaunay condition if (iff!)
+ // each circumlocutory circle (i.e. the circle that touches all three corners)
+ // of each triangle is empty of other vertices.
+ // Obviously a single (seeding) triangle fulfills this condition.
+ // If we now add one vertex, we need to reconstruct all triangles, that
+ // do not fulfill this condition with respect to the new triangle
+
+ // Find the triangles that are influenced by the new vertex
+ Vertex v=vertices[iCurrentVertex];
+ if (v == null)
+ continue; // Null is polygon stop marker. Ignore it
+ List influencedTriangles=FindInfluencedTriangles(triangles, v);
+
+ List simplices = new List();
+
+ // Reconstruction phase. First step, dissolve each triangle into it's simplices,
+ // i.e. it's "border lines"
+ // Goal is to find "inner" borders and delete them, while the hull gets conserved.
+ // Inner borders are special in the way that they always come twice, which is how we detect them
+ foreach (Triangle t in influencedTriangles)
+ {
+ List newSimplices = t.GetSimplices();
+ simplices.AddRange(newSimplices);
+ triangles.Remove(t);
+ }
+ // Now sort the simplices. That will make identical ones reside side by side in the list
+ simplices.Sort();
+
+ // Look for duplicate simplices here.
+ // Remember, they are directly side by side in the list right now,
+ // So we only check directly neighbours
+ int iSimplex;
+ List innerSimplices = new List();
+ for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards
+ {
+ if (simplices[iSimplex - 1].CompareTo(simplices[iSimplex]) == 0)
+ {
+ innerSimplices.Add(simplices[iSimplex - 1]);
+ innerSimplices.Add(simplices[iSimplex]);
+ }
+ }
+
+ foreach (Simplex s in innerSimplices)
+ {
+ simplices.Remove(s);
+ }
+
+ // each simplex still in the list belongs to the hull of the region in question
+ // The new vertex (yes, we still deal with verices here :-) ) forms a triangle
+ // with each of these simplices. Build the new triangles and add them to the list
+ foreach (Simplex s in simplices)
+ {
+ Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]);
+ if (!t.isDegraded())
+ {
+ triangles.Add(t);
+ }
+ }
+ }
+
+ }
+
+
+ static Mesh CreateBoxMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
+ // Builds the z (+ and -) surfaces of a box shaped prim
+ {
+ UInt16 hollowFactor = primShape.ProfileHollow;
+ UInt16 profileBegin = primShape.ProfileBegin;
+ UInt16 profileEnd = primShape.ProfileEnd;
+
+ // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface
+ // of a block are basically the same
+ // They may be warped differently but the shape is identical
+ // So we only create one surface as a model and derive both plus and minus surface of the block from it
+ // This is done in a model space where the block spans from -.5 to +.5 in X and Y
+ // The mapping to Scene space is done later during the "extrusion" phase
+
+ // Base
+ Vertex MM = new Vertex(-0.5f, -0.5f, 0.0f);
+ Vertex PM = new Vertex(+0.5f, -0.5f, 0.0f);
+ Vertex MP = new Vertex(-0.5f, +0.5f, 0.0f);
+ Vertex PP = new Vertex(+0.5f, +0.5f, 0.0f);
+
+ Meshing.SimpleHull outerHull = new SimpleHull();
+ outerHull.AddVertex(MM);
+ outerHull.AddVertex(PM);
+ outerHull.AddVertex(PP);
+ outerHull.AddVertex(MP);
+
+ // Deal with cuts now
+ if ((profileBegin != 0) || (profileEnd != 0))
+ {
+ double fProfileBeginAngle = profileBegin / 50000.0 * 360.0; // In degree, for easier debugging and understanding
+ fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
+ double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0
+ fProfileEndAngle -= (90.0 + 45.0);
+ if (fProfileBeginAngle < fProfileEndAngle)
+ fProfileEndAngle -= 360.0;
+
+ // Note, that we don't want to cut out a triangle, even if this is a
+ // good approximation for small cuts. Indeed we want to cut out an arc
+ // and we approximate this arc by a polygon chain
+ // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
+ // So it can easily be subtracted from the outer hull
+ int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5); // how many steps do we need with approximately 45 degree
+ double dStepWidth=(fProfileBeginAngle-fProfileEndAngle)/iSteps;
+
+ Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
+
+ // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
+ SimpleHull cutHull = new SimpleHull();
+ cutHull.AddVertex(origin);
+ for (int i=0; i 0)
+ {
+ float hollowFactorF = (float) hollowFactor/(float) 50000;
+ Vertex IMM = new Vertex(-0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
+ Vertex IPM = new Vertex(+0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
+ Vertex IMP = new Vertex(-0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
+ Vertex IPP = new Vertex(+0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
+
+ SimpleHull holeHull = new SimpleHull();
+
+ holeHull.AddVertex(IMM);
+ holeHull.AddVertex(IMP);
+ holeHull.AddVertex(IPP);
+ holeHull.AddVertex(IPM);
+
+ SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
+
+ outerHull = hollowedHull;
+
+ }
+
+ Mesh m = new Mesh();
+
+ Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
+ Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
+ Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
+
+ m.Add(Seed1);
+ m.Add(Seed2);
+ m.Add(Seed3);
+
+ m.Add(new Triangle(Seed1, Seed2, Seed3));
+ m.Add(outerHull.getVertices());
+
+ InsertVertices(m.vertices, 3, m.triangles);
+ m.DumpRaw(baseDir, primName, "Proto first Mesh");
+
+ m.Remove(Seed1);
+ m.Remove(Seed2);
+ m.Remove(Seed3);
+ m.DumpRaw(baseDir, primName, "Proto seeds removed");
+
+ m.RemoveTrianglesOutside(outerHull);
+ m.DumpRaw(baseDir, primName, "Proto outsides removed");
+
+ foreach (Triangle t in m.triangles)
+ {
+ PhysicsVector n = t.getNormal();
+ if (n.Z < 0.0)
+ t.invertNormal();
+ }
+
+ Extruder extr = new Extruder();
+
+ extr.size = size;
+
+ Mesh result = extr.Extrude(m);
+ result.DumpRaw(baseDir, primName, "Z extruded");
+ return result;
+ }
+
+ public static void CalcNormals(Mesh mesh)
+ {
+ int iTriangles = mesh.triangles.Count;
+
+ mesh.normals = new float[iTriangles*3];
+
+ int i = 0;
+ foreach (Triangle t in mesh.triangles)
+ {
+ float ux, uy, uz;
+ float vx, vy, vz;
+ float wx, wy, wz;
+
+ ux = t.v1.X;
+ uy = t.v1.Y;
+ uz = t.v1.Z;
+
+ vx = t.v2.X;
+ vy = t.v2.Y;
+ vz = t.v2.Z;
+
+ wx = t.v3.X;
+ wy = t.v3.Y;
+ wz = t.v3.Z;
+
+
+ // Vectors for edges
+ float e1x, e1y, e1z;
+ float e2x, e2y, e2z;
+
+ e1x = ux - vx;
+ e1y = uy - vy;
+ e1z = uz - vz;
+
+ e2x = ux - wx;
+ e2y = uy - wy;
+ e2z = uz - wz;
+
+
+ // Cross product for normal
+ float nx, ny, nz;
+ nx = e1y*e2z - e1z*e2y;
+ ny = e1z*e2x - e1x*e2z;
+ nz = e1x*e2y - e1y*e2x;
+
+ // Length
+ float l = (float) Math.Sqrt(nx*nx + ny*ny + nz*nz);
+
+ // Normalized "normal"
+ nx /= l;
+ ny /= l;
+ nz /= l;
+
+ mesh.normals[i] = nx;
+ mesh.normals[i + 1] = ny;
+ mesh.normals[i + 2] = nz;
+
+ i += 3;
+ }
+ }
+
+ public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
+ {
+ Mesh mesh = null;
+
+ switch (primShape.ProfileShape)
+ {
+ case ProfileShape.Square:
+ mesh=CreateBoxMesh(primName, primShape, size);
+ CalcNormals(mesh);
+ break;
+ default:
+ mesh = CreateBoxMesh(primName, primShape, size);
+ CalcNormals(mesh);
+ //Set default mesh to cube otherwise it'll return
+ // null and crash on the 'setMesh' method in the physics plugins.
+ //mesh = null;
+ break;
+ }
+
+ return mesh;
+ }
+ }
+
+}
diff --git a/OpenSim/Region/Physics/Meshing/SimpleHull.cs b/OpenSim/Region/Physics/Meshing/SimpleHull.cs
new file mode 100644
index 0000000000..c19994944a
--- /dev/null
+++ b/OpenSim/Region/Physics/Meshing/SimpleHull.cs
@@ -0,0 +1,363 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using OpenSim.Framework.Console;
+
+namespace OpenSim.Region.Physics.Meshing
+{
+ // A simple hull is a set of vertices building up to simplices that border a region
+ // The word simple referes to the fact, that this class assumes, that all simplices
+ // do not intersect
+ // Simple hulls can be added and subtracted.
+ // Vertices can be checked to lie inside a hull
+ // Also note, that the sequence of the vertices is important and defines if the region that
+ // is defined by the hull lies inside or outside the simplex chain
+ public class SimpleHull
+ {
+ List vertices = new List();
+ List holeVertices = new List(); // Only used, when the hull is hollow
+
+ // Adds a vertex to the end of the list
+ public void AddVertex(Vertex v) {
+ vertices.Add(v);
+ }
+
+ override public String ToString()
+ {
+ String result="";
+ foreach (Vertex v in vertices)
+ {
+ result += "b:" + v.ToString() + "\n";
+ }
+
+ return result;
+ }
+
+
+ public List getVertices() {
+ List newVertices = new List();
+
+ newVertices.AddRange(vertices);
+ newVertices.Add(null);
+ newVertices.AddRange(holeVertices);
+
+ return newVertices;
+ }
+
+ public SimpleHull Clone()
+ {
+ SimpleHull result = new SimpleHull();
+ foreach (Vertex v in vertices)
+ {
+ result.AddVertex(v.Clone());
+ }
+
+ foreach (Vertex v in this.holeVertices)
+ {
+ result.holeVertices.Add(v.Clone());
+ }
+
+ return result;
+ }
+
+ public bool IsPointIn(Vertex v1)
+ {
+ int iCounter=0;
+ List simplices=buildSimplexList();
+ foreach (Simplex s in simplices)
+ {
+ // Send a ray along the positive X-Direction
+ // Note, that this direction must correlate with the "below" interpretation
+ // of handling for the special cases below
+ Manager.PhysicsVector intersection = s.RayIntersect(v1, new Manager.PhysicsVector(1.0f, 0.0f, 0.0f), true);
+
+ if (intersection == null)
+ continue; // No intersection. Done. More tests to follow otherwise
+
+ // Did we hit the end of a simplex?
+ // Then this can be one of two special cases:
+ // 1. we go through a border exactly at a joint
+ // 2. we have just marginally touched a corner
+ // 3. we can slide along a border
+ // Solution: If the other vertex is "below" the ray, we don't count it
+ // Thus corners pointing down are counted twice, corners pointing up are not counted
+ // borders are counted once
+ if (intersection.IsIdentical(s.v1, 0.001f)) {
+ if (s.v2.Y < v1.Y)
+ continue;
+ }
+ // Do this for the other vertex two
+ if (intersection.IsIdentical(s.v2, 0.001f)) {
+ if (s.v1.Y buildSimplexList() {
+
+ List result = new List();
+
+ // Not asserted but assumed: at least three vertices
+ for (int i=0; i simple = buildSimplexList();
+ foreach (Simplex sTest in simple)
+ {
+ Manager.PhysicsVector vvTemp = Simplex.Intersect(sTest, s, -.001f, -.001f, 0.999f, .999f);
+
+ Vertex vTemp=null;
+ if (vvTemp != null)
+ vTemp = new Vertex(vvTemp);
+
+ if (vTemp!=null) {
+
+ Manager.PhysicsVector diff=(s.v1-vTemp);
+ float distTemp=diff.length();
+
+ if (bestIntersection==null || distTemp
+ {
+ public Vertex v1;
+ public Vertex v2;
+
+ public Simplex(Vertex _v1, Vertex _v2)
+ {
+ v1 = _v1;
+ v2 = _v2;
+ }
+
+ public int CompareTo(Simplex other)
+ {
+
+ Vertex lv1, lv2, ov1, ov2, temp;
+
+ lv1 = v1;
+ lv2 = v2;
+ ov1 = other.v1;
+ ov2 = other.v2;
+
+ if (lv1 > lv2)
+ {
+ temp = lv1;
+ lv1 = lv2;
+ lv2 = temp;
+ }
+
+ if (ov1 > ov2)
+ {
+ temp = ov1;
+ ov1 = ov2;
+ ov2 = temp;
+ }
+
+ if (lv1 > ov1)
+ {
+ return 1;
+ }
+ if (lv1 < ov1)
+ {
+ return -1;
+ }
+
+ if (lv2 > ov2)
+ {
+ return 1;
+ }
+ if (lv2 < ov2)
+ {
+ return -1;
+ }
+
+ return 0;
+ }
+
+ private static void intersectParameter(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu)
+ {
+ // Intersects two straights
+ // p1, p2, points on the straight
+ // r1, r2, directional vectors of the straight. Not necessarily of length 1!
+ // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points,
+ // thus allowing to decide whether an intersection is between two points
+
+ float r1x = r1.X;
+ float r1y = r1.Y;
+ float r2x = r2.X;
+ float r2y = r2.Y;
+
+ float denom = r1y*r2x - r1x*r2y;
+
+ float p1x = p1.X;
+ float p1y = p1.Y;
+ float p2x = p2.X;
+ float p2y = p2.Y;
+
+ float z1=-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x;
+ float z2=-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x;
+
+ if (denom == 0.0f) // Means the straights are parallel. Either no intersection or an infinite number of them
+ {
+ if (z1==0.0f) {// Means they are identical -> many, many intersections
+ lambda = Single.NaN;
+ mu = Single.NaN;
+ } else {
+ lambda = Single.PositiveInfinity;
+ mu = Single.PositiveInfinity;
+ }
+ return;
+
+ }
+
+
+
+ lambda = z1 / denom;
+ mu = z2 / denom;
+
+ }
+
+
+ // Intersects the simplex with another one.
+ // the borders are used to deal with float inaccuracies
+ // As a rule of thumb, the borders are
+ // lowerBorder1 : 0.0
+ // lowerBorder2 : 0.0
+ // upperBorder1 : 1.0
+ // upperBorder2 : 1.0
+ // Set these to values near the given parameters (e.g. 0.001 instead of 1 to exclude simplex starts safely, or to -0.001 to include them safely)
+ public static PhysicsVector Intersect(
+ Simplex s1,
+ Simplex s2,
+ float lowerBorder1,
+ float lowerBorder2,
+ float upperBorder1,
+ float upperBorder2)
+ {
+ PhysicsVector firstSimplexDirection = s1.v2 - s1.v1;
+ PhysicsVector secondSimplexDirection = s2.v2 - s2.v1;
+
+ float lambda = 0.0f;
+ float mu = 0.0f;
+
+ // Give us the parameters of an intersection. This subroutine does *not* take the constraints
+ // (intersection must be between v1 and v2 and it must be in the positive direction of the ray)
+ // into account. We do that afterwards.
+ intersectParameter(s1.v1, firstSimplexDirection, s2.v1, secondSimplexDirection, ref lambda, ref mu);
+
+ if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel.
+ return null;
+
+ if (Single.IsNaN(lambda)) // Special case. many, many intersections.
+ return null;
+
+ if (lambda > upperBorder1) // We're behind v2
+ return null;
+
+ if (lambda < lowerBorder1)
+ return null;
+
+ if (mu < lowerBorder2) // outside simplex 2
+ return null;
+
+ if (mu > upperBorder2) // outside simplex 2
+ return null;
+
+ return s1.v1 + lambda * firstSimplexDirection;
+
+ }
+
+ // Intersects the simplex with a ray. The ray is defined as all p=origin + lambda*direction
+ // where lambda >= 0
+ public PhysicsVector RayIntersect(Vertex origin, PhysicsVector direction, bool bEndsIncluded)
+ {
+ PhysicsVector simplexDirection = v2 - v1;
+
+ float lambda = 0.0f;
+ float mu = 0.0f;
+
+ // Give us the parameters of an intersection. This subroutine does *not* take the constraints
+ // (intersection must be between v1 and v2 and it must be in the positive direction of the ray)
+ // into account. We do that afterwards.
+ intersectParameter(v1, simplexDirection, origin, direction, ref lambda, ref mu);
+
+ if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel.
+ return null;
+
+ if (Single.IsNaN(lambda)) // Special case. many, many intersections.
+ return null;
+
+ if (mu < 0.0) // We're on the wrong side of the ray
+ return null;
+
+ if (lambda > 1.0) // We're behind v2
+ return null;
+
+ if (lambda == 1.0 && !bEndsIncluded)
+ return null; // The end of the simplices are not included
+
+ if (lambda < 0.0f) // we're before v1;
+ return null;
+
+ return this.v1 + lambda * simplexDirection;
+
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index 4e69175c29..646ccb556f 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -32,7 +32,7 @@ using Axiom.Math;
using Ode.NET;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
-using OpenSim.Region.Physics.OdePlugin.Meshing;
+//using OpenSim.Region.Physics.OdePlugin.Meshing;
namespace OpenSim.Region.Physics.OdePlugin
{
@@ -98,6 +98,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public IntPtr space;
public static Object OdeLock = new Object();
+ public IMesher mesher;
+
public OdeScene()
{
nearCallback = near;
@@ -137,6 +139,12 @@ namespace OpenSim.Region.Physics.OdePlugin
}
+ public override void Initialise(IMesher meshmerizer)
+ {
+ mesher = meshmerizer;
+ }
+
+
// This function blatantly ripped off from BoxStack.cs
private void near(IntPtr space, IntPtr g1, IntPtr g2)
{
@@ -308,7 +316,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation,
- Mesh mesh, PrimitiveBaseShape pbs, bool isphysical)
+ IMesh mesh, PrimitiveBaseShape pbs, bool isphysical)
{
PhysicsVector pos = new PhysicsVector();
pos.X = position.X;
@@ -409,11 +417,12 @@ namespace OpenSim.Region.Physics.OdePlugin
{
return this.AddPrimShape(primName, pbs, position, size, rotation, false);
}
+
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
PhysicsVector size, Quaternion rotation, bool isPhysical)
{
PhysicsActor result;
- Mesh mesh = null;
+ IMesh mesh = null;
switch (pbs.ProfileShape)
{
@@ -421,7 +430,7 @@ namespace OpenSim.Region.Physics.OdePlugin
/// support simple box & hollow box now; later, more shapes
if (needsMeshing(pbs))
{
- mesh = Meshmerizer.CreateMesh(primName, pbs, size);
+ mesh = mesher.CreateMesh(primName, pbs, size);
}
break;
@@ -931,7 +940,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private PhysicsVector _acceleration;
public Quaternion _orientation;
- private Mesh _mesh;
+ private IMesh _mesh;
private PrimitiveBaseShape _pbs;
private OdeScene _parent_scene;
public IntPtr prim_geom;
@@ -953,7 +962,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public OdePrim(String primName, OdeScene parent_scene, PhysicsVector pos, PhysicsVector size,
- Quaternion rotation, Mesh mesh, PrimitiveBaseShape pbs, bool pisPhysical)
+ Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical)
{
@@ -1036,15 +1045,15 @@ namespace OpenSim.Region.Physics.OdePlugin
Body = (IntPtr)0;
}
}
- public void setMesh(OdeScene parent_scene, Mesh mesh)
+ public void setMesh(OdeScene parent_scene, IMesh mesh)
{
//Kill Body so that mesh can re-make the geom
if (IsPhysical && Body != (IntPtr)0)
{
disableBody();
}
- float[] vertexList = mesh.getVertexListAsFloat(); // Note, that vertextList is pinned in memory
- int[] indexList = mesh.getIndexListAsInt(); // Also pinned, needs release after usage
+ float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
+ int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
int VertexCount = vertexList.GetLength(0)/3;
int IndexCount = indexList.GetLength(0);
@@ -1169,7 +1178,7 @@ namespace OpenSim.Region.Physics.OdePlugin
// Don't need to re-enable body.. it's done in SetMesh
- Mesh mesh = Meshmerizer.CreateMesh(oldname, _pbs, _size);
+ IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size);
// createmesh returns null when it's a shape that isn't a cube.
if (mesh != null)
setMesh(_parent_scene, mesh);
@@ -1218,7 +1227,7 @@ namespace OpenSim.Region.Physics.OdePlugin
// Construction of new prim
if (this._parent_scene.needsMeshing(_pbs))
{
- Mesh mesh = Meshmerizer.CreateMesh(oldname, _pbs, _size);
+ IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size);
setMesh(_parent_scene, mesh);
} else {
prim_geom = d.CreateBox(_parent_scene.space, _size.X, _size.Y, _size.Z);
diff --git a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
index 76121ae962..7652372758 100644
--- a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
+++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
@@ -84,6 +84,12 @@ namespace OpenSim.Region.Physics.PhysXPlugin
scene = mySdk.CreateScene();
}
+ public override void Initialise(IMesher meshmerizer)
+ {
+ // Does nothing right now
+ }
+
+
public override PhysicsActor AddAvatar(string avName, PhysicsVector position)
{
Vec3 pos = new Vec3();
diff --git a/prebuild.xml b/prebuild.xml
index 404a7502de..58ec66765b 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -251,7 +251,8 @@
-
+
+
@@ -346,8 +347,9 @@
-
-
+
+
+
@@ -356,6 +358,30 @@
+
+
+
+ ../../../../bin/Physics/
+
+
+
+
+ ../../../../bin/Physics/
+
+
+
+ ../../../../bin/
+
+
+
+
+
+
+
+
+
+
+
@@ -564,8 +590,10 @@
+
-
+
+
@@ -1108,3 +1136,4 @@
+