aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
authorTeravus Ovares2007-11-10 19:13:52 +0000
committerTeravus Ovares2007-11-10 19:13:52 +0000
commitcb07ba0d68eeb57bae1cb60f387483ff720cc29d (patch)
treea46f7b6b50e70a9f5f56a89396ba8a3f1078c19e /OpenSim/Region/Physics
parent* ODE Fixed annoying bug where resizing causes there to be a 'ghost' prim lef... (diff)
downloadopensim-SC-cb07ba0d68eeb57bae1cb60f387483ff720cc29d.zip
opensim-SC-cb07ba0d68eeb57bae1cb60f387483ff720cc29d.tar.gz
opensim-SC-cb07ba0d68eeb57bae1cb60f387483ff720cc29d.tar.bz2
opensim-SC-cb07ba0d68eeb57bae1cb60f387483ff720cc29d.tar.xz
* Moves the Meshmerizer to a separate plugin
* Experimental. Linux Prebuild needs testing. * One more update after this to remove the ODEMeshing directory....
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs7
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs145
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/TriangleIndexVertexArray.cs161
-rw-r--r--OpenSim/Region/Physics/Manager/IMesher.cs26
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs67
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs11
-rw-r--r--OpenSim/Region/Physics/Meshing/Extruder.cs83
-rw-r--r--OpenSim/Region/Physics/Meshing/HelperTypes.cs306
-rw-r--r--OpenSim/Region/Physics/Meshing/Mesh.cs213
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs393
-rw-r--r--OpenSim/Region/Physics/Meshing/SimpleHull.cs363
-rw-r--r--OpenSim/Region/Physics/Meshing/Simplex.cs198
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdePlugin.cs31
-rw-r--r--OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs6
14 files changed, 1953 insertions, 57 deletions
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
index 6377392..1d1c14f 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
@@ -70,6 +70,11 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
70 { 70 {
71 } 71 }
72 72
73 public override void Initialise(IMesher meshmerizer)
74 {
75 // Does nothing right now
76 }
77
73 public override PhysicsActor AddAvatar(string avName, PhysicsVector position) 78 public override PhysicsActor AddAvatar(string avName, PhysicsVector position)
74 { 79 {
75 BasicActor act = new BasicActor(); 80 BasicActor act = new BasicActor();
@@ -274,4 +279,4 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
274 { 279 {
275 } 280 }
276 } 281 }
277} \ No newline at end of file 282}
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;
64using System.Collections.Generic; 64using System.Collections.Generic;
65using MonoXnaCompactMaths; 65using MonoXnaCompactMaths;
66using OpenSim.Framework; 66using OpenSim.Framework;
67using OpenSim.Framework.Console;
67using OpenSim.Region.Physics.Manager; 68using OpenSim.Region.Physics.Manager;
68using XnaDevRu.BulletX; 69using XnaDevRu.BulletX;
69using XnaDevRu.BulletX.Dynamics; 70using XnaDevRu.BulletX.Dynamics;
@@ -74,15 +75,6 @@ using BoxShape=XnaDevRu.BulletX.BoxShape;
74 75
75namespace OpenSim.Region.Physics.BulletXPlugin 76namespace OpenSim.Region.Physics.BulletXPlugin
76{ 77{
77 /// <summary>
78 /// This class is only here for compilations reasons
79 /// </summary>
80 public class Mesh
81 {
82 public Mesh()
83 {
84 }
85 }
86 78
87 /// <summary> 79 /// <summary>
88 /// BulletXConversions are called now BulletXMaths 80 /// BulletXConversions are called now BulletXMaths
@@ -268,6 +260,65 @@ namespace OpenSim.Region.Physics.BulletXPlugin
268 } 260 }
269 } 261 }
270 262
263
264 // Class to detect and debug collisions
265 // Mainly used for debugging purposes
266 class CollisionDispatcherLocal : CollisionDispatcher
267 {
268
269 BulletXScene relatedScene;
270
271 public CollisionDispatcherLocal(BulletXScene s)
272 : base()
273 {
274 relatedScene=s;
275 }
276
277 public override bool NeedsCollision(CollisionObject bodyA, CollisionObject bodyB)
278 {
279 RigidBody rb;
280 BulletXCharacter bxcA=null;
281 BulletXPrim bxpA = null;
282 Type t = bodyA.GetType();
283 if (t==typeof(RigidBody)) {
284 rb = (RigidBody)bodyA;
285 relatedScene._characters.TryGetValue(rb, out bxcA);
286 relatedScene._prims.TryGetValue(rb, out bxpA);
287 }
288 String nameA;
289 if (bxcA != null)
290 nameA = bxcA._name;
291 else if (bxpA != null)
292 nameA = bxpA._name;
293 else
294 nameA = "null";
295
296 BulletXCharacter bxcB = null;
297 BulletXPrim bxpB = null;
298 t = bodyB.GetType();
299 if (t == typeof(RigidBody))
300 {
301 rb = (RigidBody)bodyB;
302 relatedScene._characters.TryGetValue(rb, out bxcB);
303 relatedScene._prims.TryGetValue(rb, out bxpB);
304 }
305 String nameB;
306 if (bxcB != null)
307 nameB = bxcB._name;
308 else if (bxpB != null)
309 nameB = bxpB._name;
310 else
311 nameB = "null";
312
313 bool needsCollision=base.NeedsCollision(bodyA, bodyB);
314
315 MainLog.Instance.Debug("BulletX", "A collision was detected between {0} and {1} --> {2}", nameA, nameB, needsCollision);
316
317
318 return needsCollision;
319 }
320 }
321
271 /// <summary> 322 /// <summary>
272 /// PhysicsScene Class for BulletX 323 /// PhysicsScene Class for BulletX
273 /// </summary> 324 /// </summary>
@@ -294,8 +345,11 @@ namespace OpenSim.Region.Physics.BulletXPlugin
294 private const int simulationSubSteps = 10; 345 private const int simulationSubSteps = 10;
295 //private float[] _heightmap; 346 //private float[] _heightmap;
296 private BulletXPlanet _simFlatPlanet; 347 private BulletXPlanet _simFlatPlanet;
297 private List<BulletXCharacter> _characters = new List<BulletXCharacter>(); 348 internal Dictionary<RigidBody, BulletXCharacter> _characters = new Dictionary<RigidBody, BulletXCharacter>();
298 private List<BulletXPrim> _prims = new List<BulletXPrim>(); 349 internal Dictionary<RigidBody, BulletXPrim> _prims = new Dictionary<RigidBody, BulletXPrim>();
350
351 public IMesher mesher;
352
299 353
300 public static float Gravity 354 public static float Gravity
301 { 355 {
@@ -334,7 +388,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
334 388
335 public BulletXScene() 389 public BulletXScene()
336 { 390 {
337 cDispatcher = new CollisionDispatcher(); 391 cDispatcher = new CollisionDispatcherLocal(this);
338 Vector3 worldMinDim = new Vector3((float) minXY, (float) minXY, (float) minZ); 392 Vector3 worldMinDim = new Vector3((float) minXY, (float) minXY, (float) minZ);
339 Vector3 worldMaxDim = new Vector3((float) maxXY, (float) maxXY, (float) maxZ); 393 Vector3 worldMaxDim = new Vector3((float) maxXY, (float) maxXY, (float) maxZ);
340 opCache = new AxisSweep3(worldMinDim, worldMaxDim, maxHandles); 394 opCache = new AxisSweep3(worldMinDim, worldMaxDim, maxHandles);
@@ -348,6 +402,12 @@ namespace OpenSim.Region.Physics.BulletXPlugin
348 //this._heightmap = new float[65536]; 402 //this._heightmap = new float[65536];
349 } 403 }
350 404
405 public override void Initialise(IMesher meshmerizer)
406 {
407 mesher = meshmerizer;
408 }
409
410
351 public override PhysicsActor AddAvatar(string avName, PhysicsVector position) 411 public override PhysicsActor AddAvatar(string avName, PhysicsVector position)
352 { 412 {
353 PhysicsVector pos = new PhysicsVector(); 413 PhysicsVector pos = new PhysicsVector();
@@ -358,7 +418,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
358 lock (BulletXLock) 418 lock (BulletXLock)
359 { 419 {
360 newAv = new BulletXCharacter(avName, this, pos); 420 newAv = new BulletXCharacter(avName, this, pos);
361 _characters.Add(newAv); 421 _characters.Add(newAv.RigidBody, newAv);
362 } 422 }
363 return newAv; 423 return newAv;
364 } 424 }
@@ -379,7 +439,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
379 ((BulletXCharacter) actor).RigidBody.ActivationState = ActivationState.DisableSimulation; 439 ((BulletXCharacter) actor).RigidBody.ActivationState = ActivationState.DisableSimulation;
380 AddForgottenRigidBody(((BulletXCharacter) actor).RigidBody); 440 AddForgottenRigidBody(((BulletXCharacter) actor).RigidBody);
381 } 441 }
382 _characters.Remove((BulletXCharacter) actor); 442 _characters.Remove(((BulletXCharacter)actor).RigidBody);
383 } 443 }
384 GC.Collect(); 444 GC.Collect();
385 } 445 }
@@ -405,7 +465,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
405 } 465 }
406 else 466 else
407 { 467 {
408 Mesh mesh = null; 468 IMesh mesh = mesher.CreateMesh(primName, pbs, size);
409 result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical); 469 result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical);
410 } 470 }
411 break; 471 break;
@@ -419,13 +479,13 @@ namespace OpenSim.Region.Physics.BulletXPlugin
419 } 479 }
420 480
421 public PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, AxiomQuaternion rotation, 481 public PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, AxiomQuaternion rotation,
422 Mesh mesh, PrimitiveBaseShape pbs, bool isPhysical) 482 IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
423 { 483 {
424 BulletXPrim newPrim = null; 484 BulletXPrim newPrim = null;
425 lock (BulletXLock) 485 lock (BulletXLock)
426 { 486 {
427 newPrim = new BulletXPrim(name, this, position, size, rotation, mesh, pbs, isPhysical); 487 newPrim = new BulletXPrim(name, this, position, size, rotation, mesh, pbs, isPhysical);
428 _prims.Add(newPrim); 488 _prims.Add(newPrim.RigidBody, newPrim);
429 } 489 }
430 return newPrim; 490 return newPrim;
431 } 491 }
@@ -446,7 +506,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
446 ((BulletXPrim) prim).RigidBody.ActivationState = ActivationState.DisableSimulation; 506 ((BulletXPrim) prim).RigidBody.ActivationState = ActivationState.DisableSimulation;
447 AddForgottenRigidBody(((BulletXPrim) prim).RigidBody); 507 AddForgottenRigidBody(((BulletXPrim) prim).RigidBody);
448 } 508 }
449 _prims.Remove((BulletXPrim) prim); 509 _prims.Remove(((BulletXPrim) prim).RigidBody);
450 } 510 }
451 GC.Collect(); 511 GC.Collect();
452 } 512 }
@@ -470,11 +530,11 @@ namespace OpenSim.Region.Physics.BulletXPlugin
470 530
471 private void MoveAllObjects(float timeStep) 531 private void MoveAllObjects(float timeStep)
472 { 532 {
473 foreach (BulletXCharacter actor in _characters) 533 foreach (BulletXCharacter actor in _characters.Values)
474 { 534 {
475 actor.Move(timeStep); 535 actor.Move(timeStep);
476 } 536 }
477 foreach (BulletXPrim prim in _prims) 537 foreach (BulletXPrim prim in _prims.Values)
478 { 538 {
479 } 539 }
480 } 540 }
@@ -482,14 +542,14 @@ namespace OpenSim.Region.Physics.BulletXPlugin
482 private void ValidateHeightForAll() 542 private void ValidateHeightForAll()
483 { 543 {
484 float _height; 544 float _height;
485 foreach (BulletXCharacter actor in _characters) 545 foreach (BulletXCharacter actor in _characters.Values)
486 { 546 {
487 //_height = HeightValue(actor.RigidBodyPosition); 547 //_height = HeightValue(actor.RigidBodyPosition);
488 _height = _simFlatPlanet.HeightValue(actor.RigidBodyPosition); 548 _height = _simFlatPlanet.HeightValue(actor.RigidBodyPosition);
489 actor.ValidateHeight(_height); 549 actor.ValidateHeight(_height);
490 //if (_simFlatPlanet.heightIsNotValid(actor.RigidBodyPosition, out _height)) actor.ValidateHeight(_height); 550 //if (_simFlatPlanet.heightIsNotValid(actor.RigidBodyPosition, out _height)) actor.ValidateHeight(_height);
491 } 551 }
492 foreach (BulletXPrim prim in _prims) 552 foreach (BulletXPrim prim in _prims.Values)
493 { 553 {
494 //_height = HeightValue(prim.RigidBodyPosition); 554 //_height = HeightValue(prim.RigidBodyPosition);
495 _height = _simFlatPlanet.HeightValue(prim.RigidBodyPosition); 555 _height = _simFlatPlanet.HeightValue(prim.RigidBodyPosition);
@@ -510,11 +570,11 @@ namespace OpenSim.Region.Physics.BulletXPlugin
510 { 570 {
511 //UpdatePosition > UpdateKinetics. 571 //UpdatePosition > UpdateKinetics.
512 //Not only position will be updated, also velocity cause acceleration. 572 //Not only position will be updated, also velocity cause acceleration.
513 foreach (BulletXCharacter actor in _characters) 573 foreach (BulletXCharacter actor in _characters.Values)
514 { 574 {
515 actor.UpdateKinetics(); 575 actor.UpdateKinetics();
516 } 576 }
517 foreach (BulletXPrim prim in _prims) 577 foreach (BulletXPrim prim in _prims.Values)
518 { 578 {
519 prim.UpdateKinetics(); 579 prim.UpdateKinetics();
520 } 580 }
@@ -646,9 +706,11 @@ namespace OpenSim.Region.Physics.BulletXPlugin
646 protected PhysicsVector m_rotationalVelocity = PhysicsVector.Zero; 706 protected PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
647 protected RigidBody rigidBody; 707 protected RigidBody rigidBody;
648 private Boolean iscolliding = false; 708 private Boolean iscolliding = false;
709 internal string _name;
649 710
650 public BulletXActor() 711 public BulletXActor(String name)
651 { 712 {
713 _name = name;
652 } 714 }
653 715
654 public override PhysicsVector Position 716 public override PhysicsVector Position
@@ -847,6 +909,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
847 } 909 }
848 public BulletXCharacter(String avName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity, 910 public BulletXCharacter(String avName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity,
849 PhysicsVector size, PhysicsVector acceleration, AxiomQuaternion orientation) 911 PhysicsVector size, PhysicsVector acceleration, AxiomQuaternion orientation)
912 : base(avName)
850 { 913 {
851 //This fields will be removed. They're temporal 914 //This fields will be removed. They're temporal
852 float _sizeX = 0.5f; 915 float _sizeX = 0.5f;
@@ -1016,14 +1079,15 @@ namespace OpenSim.Region.Physics.BulletXPlugin
1016 private bool m_lastUpdateSent = false; 1079 private bool m_lastUpdateSent = false;
1017 1080
1018 public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector size, 1081 public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector size,
1019 AxiomQuaternion rotation, Mesh mesh, PrimitiveBaseShape pbs, bool isPhysical) 1082 AxiomQuaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
1020 : this(primName, parent_scene, pos, new PhysicsVector(), size, new PhysicsVector(), rotation, mesh, pbs, isPhysical) 1083 : this(primName, parent_scene, pos, new PhysicsVector(), size, new PhysicsVector(), rotation, mesh, pbs, isPhysical)
1021 { 1084 {
1022 } 1085 }
1023 public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity, 1086 public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity,
1024 PhysicsVector size, 1087 PhysicsVector size,
1025 PhysicsVector acceleration, AxiomQuaternion rotation, Mesh mesh, PrimitiveBaseShape pbs, 1088 PhysicsVector acceleration, AxiomQuaternion rotation, IMesh mesh, PrimitiveBaseShape pbs,
1026 bool isPhysical) 1089 bool isPhysical)
1090 : base(primName)
1027 { 1091 {
1028 if ((size.X == 0) || (size.Y == 0) || (size.Z == 0)) throw new Exception("Size 0"); 1092 if ((size.X == 0) || (size.Y == 0) || (size.Z == 0)) throw new Exception("Size 0");
1029 if (rotation.Norm == 0f) rotation = AxiomQuaternion.Identity; 1093 if (rotation.Norm == 0f) rotation = AxiomQuaternion.Identity;
@@ -1037,7 +1101,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
1037 1101
1038 _parent_scene = parent_scene; 1102 _parent_scene = parent_scene;
1039 1103
1040 CreateRigidBody(parent_scene, pos, size); 1104 CreateRigidBody(parent_scene, mesh, pos, size);
1041 } 1105 }
1042 1106
1043 public override PhysicsVector Position 1107 public override PhysicsVector Position
@@ -1191,7 +1255,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
1191 } 1255 }
1192 1256
1193 #region Methods for updating values of RigidBody 1257 #region Methods for updating values of RigidBody
1194 internal protected void CreateRigidBody(BulletXScene parent_scene, PhysicsVector pos, PhysicsVector size) 1258 internal protected void CreateRigidBody(BulletXScene parent_scene, IMesh mesh, PhysicsVector pos, PhysicsVector size)
1195 { 1259 {
1196 //For RigidBody Constructor. The next values might change 1260 //For RigidBody Constructor. The next values might change
1197 float _linearDamping = 0.0f; 1261 float _linearDamping = 0.0f;
@@ -1204,7 +1268,26 @@ namespace OpenSim.Region.Physics.BulletXPlugin
1204 { 1268 {
1205 _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos); 1269 _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);
1206 //For now all prims are boxes 1270 //For now all prims are boxes
1207 CollisionShape _collisionShape = new XnaDevRu.BulletX.BoxShape(BulletXMaths.PhysicsVectorToXnaVector3(size) / 2.0f); 1271 CollisionShape _collisionShape;
1272 if (mesh == null)
1273 {
1274 _collisionShape = new XnaDevRu.BulletX.BoxShape(BulletXMaths.PhysicsVectorToXnaVector3(size) / 2.0f);
1275 } else {
1276 int iVertexCount = mesh.getVertexList().Count;
1277 int[] indices = mesh.getIndexListAsInt();
1278 Vector3[] v3Vertices = new Vector3[iVertexCount];
1279 for (int i = 0; i < iVertexCount; i++)
1280 {
1281 PhysicsVector v=mesh.getVertexList()[i];
1282 if (v != null) // Note, null has special meaning. See meshing code for details
1283 v3Vertices[i] = BulletXMaths.PhysicsVectorToXnaVector3(v);
1284 else
1285 v3Vertices[i] = MonoXnaCompactMaths.Vector3.Zero;
1286 }
1287 TriangleIndexVertexArray triMesh = new TriangleIndexVertexArray(indices, v3Vertices);
1288
1289 _collisionShape = new XnaDevRu.BulletX.TriangleMeshShape(triMesh);
1290 }
1208 DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset); 1291 DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
1209 Vector3 _localInertia = new Vector3(); 1292 Vector3 _localInertia = new Vector3();
1210 if (_physical) _collisionShape.CalculateLocalInertia(Mass, out _localInertia); //Always when mass > 0 1293 if (_physical) _collisionShape.CalculateLocalInertia(Mass, out _localInertia); //Always when mass > 0
@@ -1231,7 +1314,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
1231 rigidBody.ActivationState = ActivationState.DisableSimulation; 1314 rigidBody.ActivationState = ActivationState.DisableSimulation;
1232 this._parent_scene.AddForgottenRigidBody(rigidBody); 1315 this._parent_scene.AddForgottenRigidBody(rigidBody);
1233 } 1316 }
1234 CreateRigidBody(this._parent_scene, this._position, size); 1317 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
1235 if (_physical) Speed();//Static objects don't have linear velocity 1318 if (_physical) Speed();//Static objects don't have linear velocity
1236 ReOrient(); 1319 ReOrient();
1237 GC.Collect(); 1320 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 @@
1/*
2 Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
3 Bullet original C++ version Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22/*
23
24 This file contains a class TriangleIndexVertexArray. I tried using the class with the same name
25 from the BulletX implementation and found it unusable for the purpose of using triangle meshes
26 within BulletX as the implementation was painfully incomplete.
27 The attempt to derive from the original class failed as viable members were hidden.
28 Fiddling around with BulletX itself was not my intention.
29 So I copied the class to the BulletX-plugin and modified it.
30 If you want to fiddle around with it it's up to you to move all this to BulletX.
31 If someone someday implements the missing functionality in BulletX, feel free to remove this class.
32 It's just an ugly hack.
33
34 */
35using System;
36using System.Collections.Generic;
37using System.Text;
38using MonoXnaCompactMaths;
39
40namespace OpenSim.Region.Physics.BulletXPlugin
41{
42 /// <summary>
43 /// IndexedMesh indexes into existing vertex and index arrays, in a similar way OpenGL glDrawElements
44 /// instead of the number of indices, we pass the number of triangles
45 /// </summary>
46 public struct IndexedMesh
47 {
48 private int _numTriangles;
49 private int[] _triangleIndexBase;
50 private int _triangleIndexStride;
51 private int _numVertices;
52 private Vector3[] _vertexBase;
53 private int _vertexStride;
54
55 public IndexedMesh(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, Vector3[] vertexBase, int vertexStride)
56 {
57 _numTriangles = numTriangleIndices;
58 _triangleIndexBase = triangleIndexBase;
59 _triangleIndexStride = triangleIndexStride;
60 _vertexBase = vertexBase;
61 _numVertices = numVertices;
62 _vertexStride = vertexStride;
63 }
64
65 public IndexedMesh(int[] triangleIndexBase, Vector3[] vertexBase)
66 {
67 _numTriangles = triangleIndexBase.Length;
68 _triangleIndexBase = triangleIndexBase;
69 _triangleIndexStride = 32;
70 _vertexBase = vertexBase;
71 _numVertices = vertexBase.Length;
72 _vertexStride = 24;
73 }
74
75 public int TriangleCount { get { return _numTriangles; } set { _numTriangles = value; } }
76 public int[] TriangleIndexBase { get { return _triangleIndexBase; } set { _triangleIndexBase = value; } }
77 public int TriangleIndexStride { get { return _triangleIndexStride; } set { _triangleIndexStride = value; } }
78 public int VertexCount { get { return _numVertices; } set { _numVertices = value; } }
79 public Vector3[] VertexBase { get { return _vertexBase; } set { _vertexBase = value; } }
80 public int VertexStride { get { return _vertexStride; } set { _vertexStride = value; } }
81 }
82
83 /// <summary>
84 /// TriangleIndexVertexArray allows to use multiple meshes, by indexing into existing triangle/index arrays.
85 /// Additional meshes can be added using addIndexedMesh
86 /// </summary>
87 public class TriangleIndexVertexArray : XnaDevRu.BulletX.StridingMeshInterface
88 {
89 List<IndexedMesh> _indexedMeshes = new List<IndexedMesh>();
90
91 public TriangleIndexVertexArray() { }
92
93 public TriangleIndexVertexArray(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, Vector3[] vertexBase, int vertexStride)
94 {
95 IndexedMesh mesh = new IndexedMesh();
96 mesh.TriangleCount = numTriangleIndices;
97 mesh.TriangleIndexBase = triangleIndexBase;
98 mesh.TriangleIndexStride = triangleIndexStride;
99 mesh.VertexBase = vertexBase;
100 mesh.VertexCount = numVertices;
101 mesh.VertexStride = vertexStride;
102
103 AddIndexedMesh(mesh);
104 }
105
106 public TriangleIndexVertexArray(int[] triangleIndexBase, Vector3[] vertexBase)
107 : this(triangleIndexBase.Length, triangleIndexBase, 32, vertexBase.Length, vertexBase, 24) { }
108
109 public void AddIndexedMesh(IndexedMesh indexedMesh)
110 {
111 _indexedMeshes.Add(indexedMesh);
112 }
113
114 public override void GetLockedVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces, int subpart)
115 {
116 throw new Exception("The method or operation is not implemented.");
117 }
118
119 public override void GetLockedReadOnlyVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces, int subpart)
120 {
121 IndexedMesh m = _indexedMeshes[0];
122 Vector3[] vertexBase = m.VertexBase;
123 verts = new List<Vector3>();
124 foreach (Vector3 v in vertexBase)
125 {
126 verts.Add(v);
127 }
128 int[] indexBase = m.TriangleIndexBase;
129 indicies = new List<int>();
130 foreach (int i in indexBase)
131 {
132 indicies.Add(i);
133 }
134 numfaces = vertexBase.GetLength(0);
135 }
136
137 public override void UnLockVertexBase(int subpart)
138 {
139 throw new Exception("The method or operation is not implemented.");
140 }
141
142 public override void UnLockReadOnlyVertexBase(int subpart)
143 {
144 }
145
146 public override int SubPartsCount()
147 {
148 return _indexedMeshes.Count;
149 }
150
151 public override void PreallocateVertices(int numverts)
152 {
153 throw new Exception("The method or operation is not implemented.");
154 }
155
156 public override void PreallocateIndices(int numindices)
157 {
158 throw new Exception("The method or operation is not implemented.");
159 }
160 }
161}
diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs
new file mode 100644
index 0000000..037616c
--- /dev/null
+++ b/OpenSim/Region/Physics/Manager/IMesher.cs
@@ -0,0 +1,26 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5using OpenSim.Framework;
6
7namespace OpenSim.Region.Physics.Manager
8{
9 public interface IMesher
10 {
11 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size);
12 }
13
14 public interface IVertex {
15 }
16
17 public interface IMesh
18 {
19 List<PhysicsVector> getVertexList();
20 int[] getIndexListAsInt();
21 int[] getIndexListAsIntLocked();
22 float[] getVertexListAsFloatLocked();
23
24
25 }
26}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
index 09ebf29..47c8ae0 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Reflection; 31using System.Reflection;
32using OpenSim.Framework.Console; 32using OpenSim.Framework.Console;
33using Nini.Config;
33 34
34namespace OpenSim.Region.Physics.Manager 35namespace OpenSim.Region.Physics.Manager
35{ 36{
@@ -38,28 +39,50 @@ namespace OpenSim.Region.Physics.Manager
38 /// </summary> 39 /// </summary>
39 public class PhysicsPluginManager 40 public class PhysicsPluginManager
40 { 41 {
41 private Dictionary<string, IPhysicsPlugin> _plugins = new Dictionary<string, IPhysicsPlugin>(); 42 private Dictionary<string, IPhysicsPlugin> _PhysPlugins = new Dictionary<string, IPhysicsPlugin>();
43 private Dictionary<string, IMeshingPlugin> _MeshPlugins = new Dictionary<string, IMeshingPlugin>();
42 44
43 public PhysicsPluginManager() 45 public PhysicsPluginManager()
44 { 46 {
45 } 47 }
46 48
47 public PhysicsScene GetPhysicsScene(string engineName) 49 public PhysicsScene GetPhysicsScene(string physEngineName, string meshEngineName)
48 { 50 {
49 if (String.IsNullOrEmpty(engineName)) 51
52 if (String.IsNullOrEmpty(physEngineName))
53 {
54 return PhysicsScene.Null;
55 }
56
57 if (String.IsNullOrEmpty(meshEngineName))
50 { 58 {
51 return PhysicsScene.Null; 59 return PhysicsScene.Null;
52 } 60 }
53 61
54 if (_plugins.ContainsKey(engineName)) 62
63 IMesher meshEngine = null;
64 if (_MeshPlugins.ContainsKey(meshEngineName))
55 { 65 {
56 MainLog.Instance.Verbose("PHYSICS", "creating " + engineName); 66 MainLog.Instance.Verbose("PHYSICS", "creating meshing engine " + meshEngineName);
57 return _plugins[engineName].GetScene(); 67 meshEngine = _MeshPlugins[meshEngineName].GetMesher();
58 } 68 }
59 else 69 else
60 { 70 {
61 MainLog.Instance.Warn("PHYSICS", "couldn't find physicsEngine: {0}", engineName); 71 MainLog.Instance.Warn("PHYSICS", "couldn't find meshingEngine: {0}", meshEngineName);
62 throw new ArgumentException(String.Format("couldn't find physicsEngine: {0}", engineName)); 72 throw new ArgumentException(String.Format("couldn't find meshingEngine: {0}", meshEngineName));
73 }
74
75 if (_PhysPlugins.ContainsKey(physEngineName))
76 {
77 MainLog.Instance.Verbose("PHYSICS", "creating " + physEngineName);
78 PhysicsScene result = _PhysPlugins[physEngineName].GetScene();
79 result.Initialise(meshEngine);
80 return result;
81 }
82 else
83 {
84 MainLog.Instance.Warn("PHYSICS", "couldn't find physicsEngine: {0}", physEngineName);
85 throw new ArgumentException(String.Format("couldn't find physicsEngine: {0}", physEngineName));
63 } 86 }
64 } 87 }
65 88
@@ -85,18 +108,29 @@ namespace OpenSim.Region.Physics.Manager
85 { 108 {
86 if (!pluginType.IsAbstract) 109 if (!pluginType.IsAbstract)
87 { 110 {
88 Type typeInterface = pluginType.GetInterface("IPhysicsPlugin", true); 111 Type physTypeInterface = pluginType.GetInterface("IPhysicsPlugin", true);
89 112
90 if (typeInterface != null) 113 if (physTypeInterface != null)
91 { 114 {
92 IPhysicsPlugin plug = 115 IPhysicsPlugin plug =
93 (IPhysicsPlugin) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); 116 (IPhysicsPlugin) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
94 plug.Init(); 117 plug.Init();
95 _plugins.Add(plug.GetName(), plug); 118 _PhysPlugins.Add(plug.GetName(), plug);
96 MainLog.Instance.Verbose("PHYSICS", "Added physics engine: " + plug.GetName()); 119 MainLog.Instance.Verbose("PHYSICS", "Added physics engine: " + plug.GetName());
97 } 120 }
98 121
99 typeInterface = null; 122 Type meshTypeInterface = pluginType.GetInterface("IMeshingPlugin", true);
123
124 if (meshTypeInterface != null)
125 {
126 IMeshingPlugin plug =
127 (IMeshingPlugin)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
128 _MeshPlugins.Add(plug.GetName(), plug);
129 MainLog.Instance.Verbose("PHYSICS", "Added meshing engine: " + plug.GetName());
130 }
131
132 physTypeInterface = null;
133 meshTypeInterface = null;
100 } 134 }
101 } 135 }
102 } 136 }
@@ -127,4 +161,11 @@ namespace OpenSim.Region.Physics.Manager
127 string GetName(); 161 string GetName();
128 void Dispose(); 162 void Dispose();
129 } 163 }
130} \ No newline at end of file 164
165 public interface IMeshingPlugin
166 {
167 string GetName();
168 IMesher GetMesher();
169 }
170
171}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index 13591ea..6f19e72 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -28,6 +28,7 @@
28using Axiom.Math; 28using Axiom.Math;
29using OpenSim.Framework; 29using OpenSim.Framework;
30using OpenSim.Framework.Console; 30using OpenSim.Framework.Console;
31using OpenSim.Region.Physics.Manager;
31 32
32namespace OpenSim.Region.Physics.Manager 33namespace OpenSim.Region.Physics.Manager
33{ 34{
@@ -38,6 +39,8 @@ namespace OpenSim.Region.Physics.Manager
38 get { return new NullPhysicsScene(); } 39 get { return new NullPhysicsScene(); }
39 } 40 }
40 41
42 public abstract void Initialise(IMesher meshmerizer);
43
41 public abstract PhysicsActor AddAvatar(string avName, PhysicsVector position); 44 public abstract PhysicsActor AddAvatar(string avName, PhysicsVector position);
42 45
43 public abstract void RemoveAvatar(PhysicsActor actor); 46 public abstract void RemoveAvatar(PhysicsActor actor);
@@ -63,6 +66,12 @@ namespace OpenSim.Region.Physics.Manager
63 { 66 {
64 private static int m_workIndicator; 67 private static int m_workIndicator;
65 68
69
70 public override void Initialise(IMesher meshmerizer)
71 {
72 // Does nothing right now
73 }
74
66 public override PhysicsActor AddAvatar(string avName, PhysicsVector position) 75 public override PhysicsActor AddAvatar(string avName, PhysicsVector position)
67 { 76 {
68 MainLog.Instance.Verbose("NullPhysicsScene : AddAvatar({0})", position); 77 MainLog.Instance.Verbose("NullPhysicsScene : AddAvatar({0})", position);
@@ -123,4 +132,4 @@ namespace OpenSim.Region.Physics.Manager
123 } 132 }
124 } 133 }
125 } 134 }
126} \ No newline at end of file 135}
diff --git a/OpenSim/Region/Physics/Meshing/Extruder.cs b/OpenSim/Region/Physics/Meshing/Extruder.cs
new file mode 100644
index 0000000..63d727f
--- /dev/null
+++ b/OpenSim/Region/Physics/Meshing/Extruder.cs
@@ -0,0 +1,83 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace OpenSim.Region.Physics.Meshing
6{
7 class Extruder
8 {
9 public float startParameter;
10 public float stopParameter;
11 public Manager.PhysicsVector size;
12
13 public Mesh Extrude(Mesh m)
14 {
15 // Currently only works for iSteps=1;
16 Mesh result = new Mesh();
17
18 Mesh workingPlus = m.Clone();
19 Mesh workingMinus = m.Clone();
20
21 foreach (Vertex v in workingPlus.vertices)
22 {
23 if (v == null)
24 continue;
25
26 v.Z = +.5f;
27 v.X *= size.X;
28 v.Y *= size.Y;
29 v.Z *= size.Z;
30 }
31
32 foreach (Vertex v in workingMinus.vertices)
33 {
34 if (v == null)
35 continue;
36
37 v.Z = -.5f;
38 v.X *= size.X;
39 v.Y *= size.Y;
40 v.Z *= size.Z;
41 }
42
43 foreach (Triangle t in workingMinus.triangles)
44 {
45 t.invertNormal();
46 }
47
48 result.Append(workingMinus);
49 result.Append(workingPlus);
50
51 int iLastNull = 0;
52 for (int i = 0; i < workingPlus.vertices.Count; i++)
53 {
54 int iNext = (i + 1);
55
56 if (workingPlus.vertices[i] == null) // Can't make a simplex here
57 {
58 iLastNull = i+1;
59 continue;
60 }
61
62 if (i == workingPlus.vertices.Count-1) // End of list
63 {
64 iNext = iLastNull;
65 }
66
67 if (workingPlus.vertices[iNext] == null) // Null means wrap to begin of last segment
68 {
69 iNext = iLastNull;
70 }
71
72 Triangle tSide;
73 tSide = new Triangle(workingPlus.vertices[i], workingMinus.vertices[i], workingPlus.vertices[iNext]);
74 result.Add(tSide);
75
76 tSide = new Triangle(workingPlus.vertices[iNext], workingMinus.vertices[i], workingMinus.vertices[iNext]);
77 result.Add(tSide);
78 }
79
80 return result;
81 }
82 }
83}
diff --git a/OpenSim/Region/Physics/Meshing/HelperTypes.cs b/OpenSim/Region/Physics/Meshing/HelperTypes.cs
new file mode 100644
index 0000000..9e75826
--- /dev/null
+++ b/OpenSim/Region/Physics/Meshing/HelperTypes.cs
@@ -0,0 +1,306 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28
29using System;
30using System.Collections.Generic;
31using System.Diagnostics;
32using System.Globalization;
33using OpenSim.Framework.Console;
34using OpenSim.Region.Physics.Manager;
35
36using OpenSim.Region.Physics.Meshing;
37
38public class Vertex : PhysicsVector, IComparable<Vertex>
39{
40 public Vertex(float x, float y, float z)
41 : base(x, y, z)
42 {
43 }
44
45 public Vertex(PhysicsVector v)
46 : base(v.X, v.Y, v.Z)
47 {
48 }
49
50 public Vertex Clone()
51 {
52 return new Vertex(X, Y, Z);
53 }
54
55 public static Vertex FromAngle(double angle)
56 {
57 return new Vertex((float)Math.Cos(angle), (float)Math.Sin(angle), 0.0f);
58 }
59
60
61 public virtual bool Equals(Vertex v, float tolerance)
62 {
63 PhysicsVector diff = this - v;
64 float d = diff.length();
65 if (d < tolerance)
66 return true;
67
68 return false;
69 }
70
71
72 public int CompareTo(Vertex other)
73 {
74 if (X < other.X)
75 return -1;
76
77 if (X > other.X)
78 return 1;
79
80 if (Y < other.Y)
81 return -1;
82
83 if (Y > other.Y)
84 return 1;
85
86 if (Z < other.Z)
87 return -1;
88
89 if (Z > other.Z)
90 return 1;
91
92 return 0;
93 }
94
95 public static bool operator >(Vertex me, Vertex other)
96 {
97 return me.CompareTo(other) > 0;
98 }
99
100 public static bool operator <(Vertex me, Vertex other)
101 {
102 return me.CompareTo(other) < 0;
103 }
104 public String ToRaw()
105 {
106 // Why this stuff with the number formatter?
107 // Well, the raw format uses the english/US notation of numbers
108 // where the "," separates groups of 1000 while the "." marks the border between 1 and 10E-1.
109 // The german notation uses these characters exactly vice versa!
110 // The Float.ToString() routine is a localized one, giving different results depending on the country
111 // settings your machine works with. Unusable for a machine readable file format :-(
112 NumberFormatInfo nfi = new NumberFormatInfo();
113 nfi.NumberDecimalSeparator = ".";
114 nfi.NumberDecimalDigits = 3;
115
116 String s1 = X.ToString("N2", nfi) + " " + Y.ToString("N2", nfi) + " " + Z.ToString("N2", nfi);
117
118 return s1;
119 }
120
121}
122
123public class Triangle
124{
125 public Vertex v1;
126 public Vertex v2;
127 public Vertex v3;
128
129 private float radius_square;
130 private float cx;
131 private float cy;
132
133 public Triangle(Vertex _v1, Vertex _v2, Vertex _v3)
134 {
135 v1 = _v1;
136 v2 = _v2;
137 v3 = _v3;
138
139 CalcCircle();
140 }
141
142 public bool isInCircle(float x, float y)
143 {
144 float dx, dy;
145 float dd;
146
147 dx = x - cx;
148 dy = y - cy;
149
150 dd = dx*dx + dy*dy;
151 if (dd < radius_square)
152 return true;
153 else
154 return false;
155 }
156
157 public bool isDegraded()
158 {
159 // This means, the vertices of this triangle are somewhat strange.
160 // They either line up or at least two of them are identical
161 return (radius_square == 0.0);
162 }
163
164 private void CalcCircle()
165 {
166 // Calculate the center and the radius of a circle given by three points p1, p2, p3
167 // It is assumed, that the triangles vertices are already set correctly
168 double p1x, p2x, p1y, p2y, p3x, p3y;
169
170 // Deviation of this routine:
171 // A circle has the general equation (M-p)^2=r^2, where M and p are vectors
172 // this gives us three equations f(p)=r^2, each for one point p1, p2, p3
173 // putting respectively two equations together gives two equations
174 // f(p1)=f(p2) and f(p1)=f(p3)
175 // bringing all constant terms to one side brings them to the form
176 // M*v1=c1 resp.M*v2=c2 where v1=(p1-p2) and v2=(p1-p3) (still vectors)
177 // and c1, c2 are scalars (Naming conventions like the variables below)
178 // Now using the equations that are formed by the components of the vectors
179 // and isolate Mx lets you make one equation that only holds My
180 // The rest is straight forward and eaasy :-)
181 //
182
183 /* helping variables for temporary results */
184 double c1, c2;
185 double v1x, v1y, v2x, v2y;
186
187 double z, n;
188
189 double rx, ry;
190
191 // Readout the three points, the triangle consists of
192 p1x = v1.X;
193 p1y = v1.Y;
194
195 p2x = v2.X;
196 p2y = v2.Y;
197
198 p3x = v3.X;
199 p3y = v3.Y;
200
201 /* calc helping values first */
202 c1 = (p1x*p1x + p1y*p1y - p2x*p2x - p2y*p2y)/2;
203 c2 = (p1x*p1x + p1y*p1y - p3x*p3x - p3y*p3y)/2;
204
205 v1x = p1x - p2x;
206 v1y = p1y - p2y;
207
208 v2x = p1x - p3x;
209 v2y = p1y - p3y;
210
211 z = (c1*v2x - c2*v1x);
212 n = (v1y*v2x - v2y*v1x);
213
214 if (n == 0.0) // This is no triangle, i.e there are (at least) two points at the same location
215 {
216 radius_square = 0.0f;
217 return;
218 }
219
220 cy = (float) (z/n);
221
222 if (v2x != 0.0)
223 {
224 cx = (float) ((c2 - v2y*cy)/v2x);
225 }
226 else if (v1x != 0.0)
227 {
228 cx = (float) ((c1 - v1y*cy)/v1x);
229 }
230 else
231 {
232 Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */
233 }
234
235 rx = (p1x - cx);
236 ry = (p1y - cy);
237
238 radius_square = (float) (rx*rx + ry*ry);
239 }
240
241 public List<Simplex> GetSimplices()
242 {
243 List<Simplex> result = new List<Simplex>();
244 Simplex s1 = new Simplex(v1, v2);
245 Simplex s2 = new Simplex(v2, v3);
246 Simplex s3 = new Simplex(v3, v1);
247
248 result.Add(s1);
249 result.Add(s2);
250 result.Add(s3);
251
252 return result;
253 }
254
255 public override String ToString()
256 {
257 NumberFormatInfo nfi = new NumberFormatInfo();
258 nfi.CurrencyDecimalDigits = 2;
259 nfi.CurrencyDecimalSeparator = ".";
260
261 String s1 = "<" + v1.X.ToString(nfi) + "," + v1.Y.ToString(nfi) + "," + v1.Z.ToString(nfi) + ">";
262 String s2 = "<" + v2.X.ToString(nfi) + "," + v2.Y.ToString(nfi) + "," + v2.Z.ToString(nfi) + ">";
263 String s3 = "<" + v3.X.ToString(nfi) + "," + v3.Y.ToString(nfi) + "," + v3.Z.ToString(nfi) + ">";
264
265 return s1 + ";" + s2 + ";" + s3;
266 }
267
268 public PhysicsVector getNormal()
269 {
270 // Vertices
271
272 // Vectors for edges
273 PhysicsVector e1;
274 PhysicsVector e2;
275
276 e1 = new PhysicsVector(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
277 e2 = new PhysicsVector(v1.X - v3.X, v1.Y - v3.Y, v1.Z - v3.Z);
278
279 // Cross product for normal
280 PhysicsVector n = PhysicsVector.cross(e1, e2);
281
282 // Length
283 float l = n.length();
284
285 // Normalized "normal"
286 n = n / l;
287
288 return n;
289 }
290
291 public void invertNormal()
292 {
293 Vertex vt;
294 vt = v1;
295 v1 = v2;
296 v2 = vt;
297 }
298
299 // Dumps a triangle in the "raw faces" format, blender can import. This is for visualisation and
300 // debugging purposes
301 public String ToStringRaw()
302 {
303 String output = v1.ToRaw() + " " + v2.ToRaw() + " " +v3.ToRaw();
304 return output;
305 }
306} \ 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 0000000..fd4ce4e
--- /dev/null
+++ b/OpenSim/Region/Physics/Meshing/Mesh.cs
@@ -0,0 +1,213 @@
1using System;
2using System.IO;
3using System.Collections.Generic;
4using System.Text;
5
6using System.Runtime.InteropServices;
7
8
9using OpenSim.Region.Physics.Manager;
10
11namespace OpenSim.Region.Physics.Meshing
12{
13 public class Mesh : IMesh
14 {
15 public List<Vertex> vertices;
16 public List<Triangle> triangles;
17
18 public float[] normals;
19
20 public Mesh()
21 {
22 vertices = new List<Vertex>();
23 triangles = new List<Triangle>();
24 }
25
26 public Mesh Clone()
27 {
28 Mesh result = new Mesh();
29
30 foreach (Vertex v in vertices)
31 {
32 if (v == null)
33 result.vertices.Add(null);
34 else
35 result.vertices.Add(v.Clone());
36 }
37
38 foreach (Triangle t in triangles)
39 {
40 int iV1, iV2, iV3;
41 iV1 = this.vertices.IndexOf(t.v1);
42 iV2 = this.vertices.IndexOf(t.v2);
43 iV3 = this.vertices.IndexOf(t.v3);
44
45 Triangle newT = new Triangle(result.vertices[iV1], result.vertices[iV2], result.vertices[iV3]);
46 result.Add(newT);
47 }
48
49 return result;
50 }
51
52
53
54 public void Add(Triangle triangle)
55 {
56 int i;
57 i = vertices.IndexOf(triangle.v1);
58 if (i < 0)
59 throw new ArgumentException("Vertex v1 not known to mesh");
60 i = vertices.IndexOf(triangle.v2);
61 if (i < 0)
62 throw new ArgumentException("Vertex v2 not known to mesh");
63 i = vertices.IndexOf(triangle.v3);
64 if (i < 0)
65 throw new ArgumentException("Vertex v3 not known to mesh");
66
67 triangles.Add(triangle);
68 }
69
70 public void Add(Vertex v)
71 {
72 vertices.Add(v);
73 }
74
75 public void Remove(Vertex v)
76 {
77 int i;
78
79 // First, remove all triangles that are build on v
80 for (i = 0; i < triangles.Count; i++)
81 {
82 Triangle t = triangles[i];
83 if (t.v1 == v || t.v2 == v || t.v3 == v)
84 {
85 triangles.RemoveAt(i);
86 i--;
87 }
88 }
89
90 // Second remove v itself
91 vertices.Remove(v);
92 }
93
94 public void RemoveTrianglesOutside(SimpleHull hull)
95 {
96 int i;
97
98 for (i = 0; i < triangles.Count; i++)
99 {
100 Triangle t = triangles[i];
101 Vertex v1 = t.v1;
102 Vertex v2 = t.v2;
103 Vertex v3 = t.v3;
104 PhysicsVector m = v1 + v2 + v3;
105 m /= 3.0f;
106 if (!hull.IsPointIn(new Vertex(m)))
107 {
108 triangles.RemoveAt(i);
109 i--;
110 }
111 }
112 }
113
114
115 public void Add(List<Vertex> lv)
116 {
117 foreach (Vertex v in lv)
118 {
119 vertices.Add(v);
120 }
121 }
122
123 public List<PhysicsVector> getVertexList()
124 {
125 List<PhysicsVector> result = new List<PhysicsVector>();
126 foreach (Vertex v in vertices)
127 {
128 result.Add(v);
129 }
130 return result;
131 }
132
133 public float[] getVertexListAsFloatLocked()
134 {
135 float[] result = new float[vertices.Count * 3];
136 for (int i = 0; i < vertices.Count; i++)
137 {
138 Vertex v = vertices[i];
139 if (v == null)
140 continue;
141 result[3 * i + 0] = v.X;
142 result[3 * i + 1] = v.Y;
143 result[3 * i + 2] = v.Z;
144 }
145 GCHandle.Alloc(result, GCHandleType.Pinned);
146 return result;
147 }
148
149 public int[] getIndexListAsInt()
150 {
151 int[] result = new int[triangles.Count * 3];
152 for (int i = 0; i < triangles.Count; i++)
153 {
154 Triangle t = triangles[i];
155 result[3 * i + 0] = vertices.IndexOf(t.v1);
156 result[3 * i + 1] = vertices.IndexOf(t.v2);
157 result[3 * i + 2] = vertices.IndexOf(t.v3);
158 }
159 return result;
160 }
161
162 public int[] getIndexListAsIntLocked()
163 {
164 int[] result = getIndexListAsInt();
165 GCHandle.Alloc(result, GCHandleType.Pinned);
166 return result;
167 }
168
169
170 public void Append(Mesh newMesh)
171 {
172 foreach (Vertex v in newMesh.vertices)
173 vertices.Add(v);
174
175 foreach (Triangle t in newMesh.triangles)
176 Add(t);
177
178 }
179
180 // Do a linear transformation of mesh.
181 public void TransformLinear(float[,] matrix, float[] offset)
182 {
183 foreach (Vertex v in vertices)
184 {
185 if (v == null)
186 continue;
187 float x, y, z;
188 x = v.X * matrix[0, 0] + v.Y * matrix[1, 0] + v.Z * matrix[2, 0];
189 y = v.X * matrix[0, 1] + v.Y * matrix[1, 1] + v.Z * matrix[2, 1];
190 z = v.X * matrix[0, 2] + v.Y * matrix[1, 2] + v.Z * matrix[2, 2];
191 v.X = x + offset[0];
192 v.Y = y + offset[1];
193 v.Z = z + offset[2];
194 }
195 }
196
197 public void DumpRaw(String path, String name, String title)
198 {
199 if (path == null)
200 return;
201 String fileName = name + "_" + title + ".raw";
202 String completePath = Path.Combine(path, fileName);
203 StreamWriter sw = new StreamWriter(completePath);
204 foreach (Triangle t in triangles)
205 {
206 String s = t.ToStringRaw();
207 sw.WriteLine(s);
208 }
209 sw.Close();
210 }
211 }
212
213}
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
new file mode 100644
index 0000000..da4ee58
--- /dev/null
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -0,0 +1,393 @@
1/*
2* Copyright (c) Contributors, http://opensimulator.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7* * Redistributions of source code must retain the above copyright
8* notice, this list of conditions and the following disclaimer.
9* * Redistributions in binary form must reproduce the above copyright
10* notice, this list of conditions and the following disclaimer in the
11* documentation and/or other materials provided with the distribution.
12* * Neither the name of the OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28
29using System;
30using System.IO;
31using System.Globalization;
32using System.Diagnostics;
33using System.Collections.Generic;
34using System.Runtime.InteropServices;
35using OpenSim.Framework;
36using OpenSim.Framework.Console;
37using OpenSim.Region.Physics.Manager;
38
39namespace OpenSim.Region.Physics.Meshing
40{
41
42 public class MeshmerizerPlugin : IMeshingPlugin
43 {
44 public MeshmerizerPlugin()
45 {
46 }
47
48 public string GetName()
49 {
50 return "Meshmerizer";
51 }
52
53 public IMesher GetMesher()
54 {
55 return new Meshmerizer();
56 }
57 }
58
59 public class Meshmerizer : IMesher
60 {
61 // Setting baseDir to a path will enable the dumping of raw files
62 // raw files can be imported by blender so a visual inspection of the results can be done
63 // const string baseDir = "rawFiles";
64 const string baseDir = null;
65
66 static void IntersectionParameterPD(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu)
67 {
68 // p1, p2, points on the straight
69 // r1, r2, directional vectors of the straight. Not necessarily of length 1!
70 // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points,
71 // thus allowing to decide whether an intersection is between two points
72
73 float r1x = r1.X;
74 float r1y = r1.Y;
75 float r2x = r2.X;
76 float r2y = r2.Y;
77
78 float denom = r1y*r2x - r1x*r2y;
79
80 if (denom == 0.0)
81 {
82 lambda = Single.NaN;
83 mu = Single.NaN;
84 return;
85 }
86
87 float p1x = p1.X;
88 float p1y = p1.Y;
89 float p2x = p2.X;
90 float p2y = p2.Y;
91 lambda = (-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x) / denom;
92 mu = (-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x) / denom;
93
94 }
95
96 private static List<Triangle> FindInfluencedTriangles(List<Triangle> triangles, Vertex v)
97 {
98 List<Triangle> influenced = new List<Triangle>();
99 foreach (Triangle t in triangles)
100 {
101 if (t.isInCircle(v.X, v.Y))
102 {
103 influenced.Add(t);
104 }
105 }
106 return influenced;
107 }
108
109
110 private static void InsertVertices(List<Vertex> vertices, int usedForSeed, List<Triangle> triangles)
111 {
112 // This is a variant of the delaunay algorithm
113 // each time a new vertex is inserted, all triangles that are influenced by it are deleted
114 // and replaced by new ones including the new vertex
115 // It is not very time efficient but easy to implement.
116
117 int iCurrentVertex;
118 int iMaxVertex = vertices.Count;
119 for (iCurrentVertex = usedForSeed; iCurrentVertex < iMaxVertex; iCurrentVertex++)
120 {
121 // Background: A triangle mesh fulfills the delaunay condition if (iff!)
122 // each circumlocutory circle (i.e. the circle that touches all three corners)
123 // of each triangle is empty of other vertices.
124 // Obviously a single (seeding) triangle fulfills this condition.
125 // If we now add one vertex, we need to reconstruct all triangles, that
126 // do not fulfill this condition with respect to the new triangle
127
128 // Find the triangles that are influenced by the new vertex
129 Vertex v=vertices[iCurrentVertex];
130 if (v == null)
131 continue; // Null is polygon stop marker. Ignore it
132 List<Triangle> influencedTriangles=FindInfluencedTriangles(triangles, v);
133
134 List<Simplex> simplices = new List<Simplex>();
135
136 // Reconstruction phase. First step, dissolve each triangle into it's simplices,
137 // i.e. it's "border lines"
138 // Goal is to find "inner" borders and delete them, while the hull gets conserved.
139 // Inner borders are special in the way that they always come twice, which is how we detect them
140 foreach (Triangle t in influencedTriangles)
141 {
142 List<Simplex> newSimplices = t.GetSimplices();
143 simplices.AddRange(newSimplices);
144 triangles.Remove(t);
145 }
146 // Now sort the simplices. That will make identical ones reside side by side in the list
147 simplices.Sort();
148
149 // Look for duplicate simplices here.
150 // Remember, they are directly side by side in the list right now,
151 // So we only check directly neighbours
152 int iSimplex;
153 List<Simplex> innerSimplices = new List<Simplex>();
154 for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards
155 {
156 if (simplices[iSimplex - 1].CompareTo(simplices[iSimplex]) == 0)
157 {
158 innerSimplices.Add(simplices[iSimplex - 1]);
159 innerSimplices.Add(simplices[iSimplex]);
160 }
161 }
162
163 foreach (Simplex s in innerSimplices)
164 {
165 simplices.Remove(s);
166 }
167
168 // each simplex still in the list belongs to the hull of the region in question
169 // The new vertex (yes, we still deal with verices here :-) ) forms a triangle
170 // with each of these simplices. Build the new triangles and add them to the list
171 foreach (Simplex s in simplices)
172 {
173 Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]);
174 if (!t.isDegraded())
175 {
176 triangles.Add(t);
177 }
178 }
179 }
180
181 }
182
183
184 static Mesh CreateBoxMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
185 // Builds the z (+ and -) surfaces of a box shaped prim
186 {
187 UInt16 hollowFactor = primShape.ProfileHollow;
188 UInt16 profileBegin = primShape.ProfileBegin;
189 UInt16 profileEnd = primShape.ProfileEnd;
190
191 // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface
192 // of a block are basically the same
193 // They may be warped differently but the shape is identical
194 // So we only create one surface as a model and derive both plus and minus surface of the block from it
195 // This is done in a model space where the block spans from -.5 to +.5 in X and Y
196 // The mapping to Scene space is done later during the "extrusion" phase
197
198 // Base
199 Vertex MM = new Vertex(-0.5f, -0.5f, 0.0f);
200 Vertex PM = new Vertex(+0.5f, -0.5f, 0.0f);
201 Vertex MP = new Vertex(-0.5f, +0.5f, 0.0f);
202 Vertex PP = new Vertex(+0.5f, +0.5f, 0.0f);
203
204 Meshing.SimpleHull outerHull = new SimpleHull();
205 outerHull.AddVertex(MM);
206 outerHull.AddVertex(PM);
207 outerHull.AddVertex(PP);
208 outerHull.AddVertex(MP);
209
210 // Deal with cuts now
211 if ((profileBegin != 0) || (profileEnd != 0))
212 {
213 double fProfileBeginAngle = profileBegin / 50000.0 * 360.0; // In degree, for easier debugging and understanding
214 fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
215 double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0
216 fProfileEndAngle -= (90.0 + 45.0);
217 if (fProfileBeginAngle < fProfileEndAngle)
218 fProfileEndAngle -= 360.0;
219
220 // Note, that we don't want to cut out a triangle, even if this is a
221 // good approximation for small cuts. Indeed we want to cut out an arc
222 // and we approximate this arc by a polygon chain
223 // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
224 // So it can easily be subtracted from the outer hull
225 int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5); // how many steps do we need with approximately 45 degree
226 double dStepWidth=(fProfileBeginAngle-fProfileEndAngle)/iSteps;
227
228 Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
229
230 // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
231 SimpleHull cutHull = new SimpleHull();
232 cutHull.AddVertex(origin);
233 for (int i=0; i<iSteps; i++) {
234 double angle=fProfileBeginAngle-i*dStepWidth; // we count against the angle orientation!!!!
235 Vertex v = Vertex.FromAngle(angle * Math.PI / 180.0);
236 cutHull.AddVertex(v);
237 }
238 Vertex legEnd = Vertex.FromAngle(fProfileEndAngle * Math.PI / 180.0); // Calculated separately to avoid errors
239 cutHull.AddVertex(legEnd);
240
241 MainLog.Instance.Debug("Starting cutting of the hollow shape from the prim {1}", 0, primName);
242 SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
243
244 outerHull = cuttedHull;
245 }
246
247 // Deal with the hole here
248 if (hollowFactor > 0)
249 {
250 float hollowFactorF = (float) hollowFactor/(float) 50000;
251 Vertex IMM = new Vertex(-0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
252 Vertex IPM = new Vertex(+0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
253 Vertex IMP = new Vertex(-0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
254 Vertex IPP = new Vertex(+0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
255
256 SimpleHull holeHull = new SimpleHull();
257
258 holeHull.AddVertex(IMM);
259 holeHull.AddVertex(IMP);
260 holeHull.AddVertex(IPP);
261 holeHull.AddVertex(IPM);
262
263 SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
264
265 outerHull = hollowedHull;
266
267 }
268
269 Mesh m = new Mesh();
270
271 Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
272 Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
273 Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
274
275 m.Add(Seed1);
276 m.Add(Seed2);
277 m.Add(Seed3);
278
279 m.Add(new Triangle(Seed1, Seed2, Seed3));
280 m.Add(outerHull.getVertices());
281
282 InsertVertices(m.vertices, 3, m.triangles);
283 m.DumpRaw(baseDir, primName, "Proto first Mesh");
284
285 m.Remove(Seed1);
286 m.Remove(Seed2);
287 m.Remove(Seed3);
288 m.DumpRaw(baseDir, primName, "Proto seeds removed");
289
290 m.RemoveTrianglesOutside(outerHull);
291 m.DumpRaw(baseDir, primName, "Proto outsides removed");
292
293 foreach (Triangle t in m.triangles)
294 {
295 PhysicsVector n = t.getNormal();
296 if (n.Z < 0.0)
297 t.invertNormal();
298 }
299
300 Extruder extr = new Extruder();
301
302 extr.size = size;
303
304 Mesh result = extr.Extrude(m);
305 result.DumpRaw(baseDir, primName, "Z extruded");
306 return result;
307 }
308
309 public static void CalcNormals(Mesh mesh)
310 {
311 int iTriangles = mesh.triangles.Count;
312
313 mesh.normals = new float[iTriangles*3];
314
315 int i = 0;
316 foreach (Triangle t in mesh.triangles)
317 {
318 float ux, uy, uz;
319 float vx, vy, vz;
320 float wx, wy, wz;
321
322 ux = t.v1.X;
323 uy = t.v1.Y;
324 uz = t.v1.Z;
325
326 vx = t.v2.X;
327 vy = t.v2.Y;
328 vz = t.v2.Z;
329
330 wx = t.v3.X;
331 wy = t.v3.Y;
332 wz = t.v3.Z;
333
334
335 // Vectors for edges
336 float e1x, e1y, e1z;
337 float e2x, e2y, e2z;
338
339 e1x = ux - vx;
340 e1y = uy - vy;
341 e1z = uz - vz;
342
343 e2x = ux - wx;
344 e2y = uy - wy;
345 e2z = uz - wz;
346
347
348 // Cross product for normal
349 float nx, ny, nz;
350 nx = e1y*e2z - e1z*e2y;
351 ny = e1z*e2x - e1x*e2z;
352 nz = e1x*e2y - e1y*e2x;
353
354 // Length
355 float l = (float) Math.Sqrt(nx*nx + ny*ny + nz*nz);
356
357 // Normalized "normal"
358 nx /= l;
359 ny /= l;
360 nz /= l;
361
362 mesh.normals[i] = nx;
363 mesh.normals[i + 1] = ny;
364 mesh.normals[i + 2] = nz;
365
366 i += 3;
367 }
368 }
369
370 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
371 {
372 Mesh mesh = null;
373
374 switch (primShape.ProfileShape)
375 {
376 case ProfileShape.Square:
377 mesh=CreateBoxMesh(primName, primShape, size);
378 CalcNormals(mesh);
379 break;
380 default:
381 mesh = CreateBoxMesh(primName, primShape, size);
382 CalcNormals(mesh);
383 //Set default mesh to cube otherwise it'll return
384 // null and crash on the 'setMesh' method in the physics plugins.
385 //mesh = null;
386 break;
387 }
388
389 return mesh;
390 }
391 }
392
393}
diff --git a/OpenSim/Region/Physics/Meshing/SimpleHull.cs b/OpenSim/Region/Physics/Meshing/SimpleHull.cs
new file mode 100644
index 0000000..c199949
--- /dev/null
+++ b/OpenSim/Region/Physics/Meshing/SimpleHull.cs
@@ -0,0 +1,363 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5using OpenSim.Framework.Console;
6
7namespace OpenSim.Region.Physics.Meshing
8{
9 // A simple hull is a set of vertices building up to simplices that border a region
10 // The word simple referes to the fact, that this class assumes, that all simplices
11 // do not intersect
12 // Simple hulls can be added and subtracted.
13 // Vertices can be checked to lie inside a hull
14 // Also note, that the sequence of the vertices is important and defines if the region that
15 // is defined by the hull lies inside or outside the simplex chain
16 public class SimpleHull
17 {
18 List<Vertex> vertices = new List<Vertex>();
19 List<Vertex> holeVertices = new List<Vertex>(); // Only used, when the hull is hollow
20
21 // Adds a vertex to the end of the list
22 public void AddVertex(Vertex v) {
23 vertices.Add(v);
24 }
25
26 override public String ToString()
27 {
28 String result="";
29 foreach (Vertex v in vertices)
30 {
31 result += "b:" + v.ToString() + "\n";
32 }
33
34 return result;
35 }
36
37
38 public List<Vertex> getVertices() {
39 List<Vertex> newVertices = new List<Vertex>();
40
41 newVertices.AddRange(vertices);
42 newVertices.Add(null);
43 newVertices.AddRange(holeVertices);
44
45 return newVertices;
46 }
47
48 public SimpleHull Clone()
49 {
50 SimpleHull result = new SimpleHull();
51 foreach (Vertex v in vertices)
52 {
53 result.AddVertex(v.Clone());
54 }
55
56 foreach (Vertex v in this.holeVertices)
57 {
58 result.holeVertices.Add(v.Clone());
59 }
60
61 return result;
62 }
63
64 public bool IsPointIn(Vertex v1)
65 {
66 int iCounter=0;
67 List<Simplex> simplices=buildSimplexList();
68 foreach (Simplex s in simplices)
69 {
70 // Send a ray along the positive X-Direction
71 // Note, that this direction must correlate with the "below" interpretation
72 // of handling for the special cases below
73 Manager.PhysicsVector intersection = s.RayIntersect(v1, new Manager.PhysicsVector(1.0f, 0.0f, 0.0f), true);
74
75 if (intersection == null)
76 continue; // No intersection. Done. More tests to follow otherwise
77
78 // Did we hit the end of a simplex?
79 // Then this can be one of two special cases:
80 // 1. we go through a border exactly at a joint
81 // 2. we have just marginally touched a corner
82 // 3. we can slide along a border
83 // Solution: If the other vertex is "below" the ray, we don't count it
84 // Thus corners pointing down are counted twice, corners pointing up are not counted
85 // borders are counted once
86 if (intersection.IsIdentical(s.v1, 0.001f)) {
87 if (s.v2.Y < v1.Y)
88 continue;
89 }
90 // Do this for the other vertex two
91 if (intersection.IsIdentical(s.v2, 0.001f)) {
92 if (s.v1.Y<v1.Y)
93 continue;
94 }
95 iCounter++;
96 }
97
98 return iCounter % 2 == 1; // Point is inside if the number of intersections is odd
99 }
100
101 public bool containsPointsFrom(SimpleHull otherHull)
102 {
103 foreach (Vertex v in otherHull.vertices)
104 {
105 if (IsPointIn(v))
106 return true;
107 }
108
109 return false;
110 }
111
112
113 List<Simplex> buildSimplexList() {
114
115 List<Simplex> result = new List<Simplex>();
116
117 // Not asserted but assumed: at least three vertices
118 for (int i=0; i<vertices.Count-1; i++) {
119 Simplex s=new Simplex(vertices[i], vertices[i+1]);
120 result.Add(s);
121 }
122 Simplex s1=new Simplex(vertices[vertices.Count-1], vertices[0]);
123 result.Add(s1);
124
125 if (holeVertices.Count==0)
126 return result;
127
128 // Same here. At least three vertices in hole assumed
129 for (int i = 0; i < holeVertices.Count - 1; i++)
130 {
131 Simplex s = new Simplex(holeVertices[i], holeVertices[i + 1]);
132 result.Add(s);
133 }
134
135 s1 = new Simplex(holeVertices[holeVertices.Count - 1], holeVertices[0]);
136 result.Add(s1);
137 return result;
138 }
139
140 bool InsertVertex(Vertex v, int iAfter)
141 {
142 vertices.Insert(iAfter + 1, v);
143 return true;
144 }
145
146 Vertex getNextVertex(Vertex currentVertex)
147 {
148 int iCurrentIndex;
149 iCurrentIndex = vertices.IndexOf(currentVertex);
150
151 // Error handling for iCurrentIndex==-1 should go here (and probably never will)
152
153 iCurrentIndex++;
154 if (iCurrentIndex == vertices.Count)
155 iCurrentIndex = 0;
156
157 return vertices[iCurrentIndex];
158 }
159
160 public Vertex FindVertex(Vertex vBase, float tolerance) {
161 foreach (Vertex v in vertices) {
162 if (v.IsIdentical(vBase, tolerance))
163 return v;
164 }
165
166 return null;
167 }
168
169 public void FindIntersection(Simplex s, ref Vertex Intersection, ref Vertex nextVertex)
170 {
171 Vertex bestIntersection=null;
172 float distToV1=Single.PositiveInfinity;
173 Simplex bestIntersectingSimplex=null;
174
175 List<Simplex> simple = buildSimplexList();
176 foreach (Simplex sTest in simple)
177 {
178 Manager.PhysicsVector vvTemp = Simplex.Intersect(sTest, s, -.001f, -.001f, 0.999f, .999f);
179
180 Vertex vTemp=null;
181 if (vvTemp != null)
182 vTemp = new Vertex(vvTemp);
183
184 if (vTemp!=null) {
185
186 Manager.PhysicsVector diff=(s.v1-vTemp);
187 float distTemp=diff.length();
188
189 if (bestIntersection==null || distTemp<distToV1) {
190 bestIntersection=vTemp;
191 distToV1=distTemp;
192 bestIntersectingSimplex = sTest;
193 }
194
195 } // end if vTemp
196
197 } // end foreach
198
199 Intersection = bestIntersection;
200 if (bestIntersectingSimplex != null)
201 nextVertex = bestIntersectingSimplex.v2;
202 else
203 nextVertex = null;
204 }
205
206
207 public static SimpleHull SubtractHull(SimpleHull baseHull, SimpleHull otherHull)
208 {
209
210 SimpleHull baseHullClone = baseHull.Clone();
211 SimpleHull otherHullClone = otherHull.Clone();
212 bool intersects = false;
213
214 MainLog.Instance.Debug("State before intersection detection");
215 MainLog.Instance.Debug("The baseHull is:\n{1}", 0, baseHullClone.ToString());
216 MainLog.Instance.Debug("The otherHull is:\n{1}", 0, otherHullClone.ToString());
217
218 {
219 int iBase, iOther;
220
221 // Insert into baseHull
222 for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
223 {
224 int iBaseNext = (iBase + 1) % baseHullClone.vertices.Count;
225 Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]);
226
227 for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++)
228 {
229 int iOtherNext = (iOther + 1) % otherHullClone.vertices.Count;
230 Simplex sOther = new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]);
231
232 Manager.PhysicsVector intersect = Simplex.Intersect(sBase, sOther, 0.001f, -.001f, 0.999f, 1.001f);
233 if (intersect != null)
234 {
235 Vertex vIntersect = new Vertex(intersect);
236 baseHullClone.vertices.Insert(iBase + 1, vIntersect);
237 sBase.v2 = vIntersect;
238 intersects = true;
239 }
240 }
241 }
242 }
243
244 MainLog.Instance.Debug("State after intersection detection for the base hull");
245 MainLog.Instance.Debug("The baseHull is:\n{1}", 0, baseHullClone.ToString());
246
247 {
248 int iOther, iBase;
249
250 // Insert into otherHull
251 for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++)
252 {
253 int iOtherNext = (iOther + 1) % otherHullClone.vertices.Count;
254 Simplex sOther = new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]);
255
256 for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
257 {
258 int iBaseNext = (iBase + 1) % baseHullClone.vertices.Count;
259 Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]);
260
261 Manager.PhysicsVector intersect = Simplex.Intersect(sBase, sOther, -.001f, 0.001f, 1.001f, 0.999f);
262 if (intersect != null)
263 {
264 Vertex vIntersect = new Vertex(intersect);
265 otherHullClone.vertices.Insert(iOther + 1, vIntersect);
266 sOther.v2 = vIntersect;
267 intersects = true;
268 }
269 }
270 }
271 }
272
273 MainLog.Instance.Debug("State after intersection detection for the base hull");
274 MainLog.Instance.Debug("The otherHull is:\n{1}", 0, otherHullClone.ToString());
275
276
277 bool otherIsInBase = baseHullClone.containsPointsFrom(otherHullClone);
278 if (!intersects && otherIsInBase)
279 {
280 // We have a hole here
281 baseHullClone.holeVertices = otherHullClone.vertices;
282 return baseHullClone;
283 }
284
285
286 SimpleHull result = new SimpleHull();
287
288 // Find a good starting Simplex from baseHull
289 // A good starting simplex is one that is outside otherHull
290 // Such a simplex must exist, otherwise the result will be empty
291 Vertex baseStartVertex = null;
292 {
293 int iBase;
294 for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
295 {
296 int iBaseNext = (iBase + 1) % baseHullClone.vertices.Count;
297 Vertex center = new Vertex((baseHullClone.vertices[iBase] + baseHullClone.vertices[iBaseNext]) / 2.0f);
298 bool isOutside = !otherHullClone.IsPointIn(center);
299 if (isOutside)
300 {
301 baseStartVertex = baseHullClone.vertices[iBaseNext];
302 break;
303 }
304 }
305 }
306
307
308 if (baseStartVertex == null) // i.e. no simplex fulfilled the "outside" condition.
309 // In otherwords, subtractHull completely embraces baseHull
310 {
311 return result;
312 }
313
314 // The simplex that *starts* with baseStartVertex is outside the cutting hull,
315 // so we can start our walk with the next vertex without loosing a branch
316 Vertex V1 = baseStartVertex;
317 bool onBase = true;
318
319 // And here is how we do the magic :-)
320 // Start on the base hull.
321 // Walk the vertices in the positive direction
322 // For each vertex check, whether it is a vertex shared with the other hull
323 // if this is the case, switch over to walking the other vertex list.
324 // Note: The other hull *must* go backwards to our starting point (via several orther vertices)
325 // Thus it is important that the cutting hull has the inverse directional sense than the
326 // base hull!!!!!!!!! (means if base goes CW around it's center cutting hull must go CCW)
327
328 bool done = false;
329 while (!done)
330 {
331 result.AddVertex(V1);
332 Vertex nextVertex = null;
333 if (onBase)
334 {
335 nextVertex = otherHullClone.FindVertex(V1, 0.001f);
336 }
337 else
338 {
339 nextVertex = baseHullClone.FindVertex(V1, 0.001f);
340 }
341
342 if (nextVertex != null) // A node that represents an intersection
343 {
344 V1 = nextVertex; // Needed to find the next vertex on the other hull
345 onBase = !onBase;
346 }
347
348 if (onBase)
349 V1 = baseHullClone.getNextVertex(V1);
350 else
351 V1 = otherHullClone.getNextVertex(V1);
352
353 if (V1 == baseStartVertex)
354 done = true;
355 }
356
357 MainLog.Instance.Debug("The resulting Hull is:\n{1}", 0, result.ToString());
358
359 return result;
360
361 }
362 }
363}
diff --git a/OpenSim/Region/Physics/Meshing/Simplex.cs b/OpenSim/Region/Physics/Meshing/Simplex.cs
new file mode 100644
index 0000000..4944f22
--- /dev/null
+++ b/OpenSim/Region/Physics/Meshing/Simplex.cs
@@ -0,0 +1,198 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using OpenSim.Region.Physics.Manager;
5
6namespace OpenSim.Region.Physics.Meshing
7{
8 // A simplex is a section of a straight line.
9 // It is defined by its endpoints, i.e. by two vertices
10 // Operation on vertices are
11 public class Simplex : IComparable<Simplex>
12 {
13 public Vertex v1;
14 public Vertex v2;
15
16 public Simplex(Vertex _v1, Vertex _v2)
17 {
18 v1 = _v1;
19 v2 = _v2;
20 }
21
22 public int CompareTo(Simplex other)
23 {
24
25 Vertex lv1, lv2, ov1, ov2, temp;
26
27 lv1 = v1;
28 lv2 = v2;
29 ov1 = other.v1;
30 ov2 = other.v2;
31
32 if (lv1 > lv2)
33 {
34 temp = lv1;
35 lv1 = lv2;
36 lv2 = temp;
37 }
38
39 if (ov1 > ov2)
40 {
41 temp = ov1;
42 ov1 = ov2;
43 ov2 = temp;
44 }
45
46 if (lv1 > ov1)
47 {
48 return 1;
49 }
50 if (lv1 < ov1)
51 {
52 return -1;
53 }
54
55 if (lv2 > ov2)
56 {
57 return 1;
58 }
59 if (lv2 < ov2)
60 {
61 return -1;
62 }
63
64 return 0;
65 }
66
67 private static void intersectParameter(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2, PhysicsVector r2, ref float lambda, ref float mu)
68 {
69 // Intersects two straights
70 // p1, p2, points on the straight
71 // r1, r2, directional vectors of the straight. Not necessarily of length 1!
72 // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points,
73 // thus allowing to decide whether an intersection is between two points
74
75 float r1x = r1.X;
76 float r1y = r1.Y;
77 float r2x = r2.X;
78 float r2y = r2.Y;
79
80 float denom = r1y*r2x - r1x*r2y;
81
82 float p1x = p1.X;
83 float p1y = p1.Y;
84 float p2x = p2.X;
85 float p2y = p2.Y;
86
87 float z1=-p2x * r2y + p1x * r2y + (p2y - p1y) * r2x;
88 float z2=-p2x * r1y + p1x * r1y + (p2y - p1y) * r1x;
89
90 if (denom == 0.0f) // Means the straights are parallel. Either no intersection or an infinite number of them
91 {
92 if (z1==0.0f) {// Means they are identical -> many, many intersections
93 lambda = Single.NaN;
94 mu = Single.NaN;
95 } else {
96 lambda = Single.PositiveInfinity;
97 mu = Single.PositiveInfinity;
98 }
99 return;
100
101 }
102
103
104
105 lambda = z1 / denom;
106 mu = z2 / denom;
107
108 }
109
110
111 // Intersects the simplex with another one.
112 // the borders are used to deal with float inaccuracies
113 // As a rule of thumb, the borders are
114 // lowerBorder1 : 0.0
115 // lowerBorder2 : 0.0
116 // upperBorder1 : 1.0
117 // upperBorder2 : 1.0
118 // 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)
119 public static PhysicsVector Intersect(
120 Simplex s1,
121 Simplex s2,
122 float lowerBorder1,
123 float lowerBorder2,
124 float upperBorder1,
125 float upperBorder2)
126 {
127 PhysicsVector firstSimplexDirection = s1.v2 - s1.v1;
128 PhysicsVector secondSimplexDirection = s2.v2 - s2.v1;
129
130 float lambda = 0.0f;
131 float mu = 0.0f;
132
133 // Give us the parameters of an intersection. This subroutine does *not* take the constraints
134 // (intersection must be between v1 and v2 and it must be in the positive direction of the ray)
135 // into account. We do that afterwards.
136 intersectParameter(s1.v1, firstSimplexDirection, s2.v1, secondSimplexDirection, ref lambda, ref mu);
137
138 if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel.
139 return null;
140
141 if (Single.IsNaN(lambda)) // Special case. many, many intersections.
142 return null;
143
144 if (lambda > upperBorder1) // We're behind v2
145 return null;
146
147 if (lambda < lowerBorder1)
148 return null;
149
150 if (mu < lowerBorder2) // outside simplex 2
151 return null;
152
153 if (mu > upperBorder2) // outside simplex 2
154 return null;
155
156 return s1.v1 + lambda * firstSimplexDirection;
157
158 }
159
160 // Intersects the simplex with a ray. The ray is defined as all p=origin + lambda*direction
161 // where lambda >= 0
162 public PhysicsVector RayIntersect(Vertex origin, PhysicsVector direction, bool bEndsIncluded)
163 {
164 PhysicsVector simplexDirection = v2 - v1;
165
166 float lambda = 0.0f;
167 float mu = 0.0f;
168
169 // Give us the parameters of an intersection. This subroutine does *not* take the constraints
170 // (intersection must be between v1 and v2 and it must be in the positive direction of the ray)
171 // into account. We do that afterwards.
172 intersectParameter(v1, simplexDirection, origin, direction, ref lambda, ref mu);
173
174 if (Single.IsInfinity(lambda)) // Special case. No intersection at all. directions parallel.
175 return null;
176
177 if (Single.IsNaN(lambda)) // Special case. many, many intersections.
178 return null;
179
180 if (mu < 0.0) // We're on the wrong side of the ray
181 return null;
182
183 if (lambda > 1.0) // We're behind v2
184 return null;
185
186 if (lambda == 1.0 && !bEndsIncluded)
187 return null; // The end of the simplices are not included
188
189 if (lambda < 0.0f) // we're before v1;
190 return null;
191
192 return this.v1 + lambda * simplexDirection;
193
194 }
195
196
197 }
198} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index 4e69175..646ccb5 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -32,7 +32,7 @@ using Axiom.Math;
32using Ode.NET; 32using Ode.NET;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Region.Physics.Manager; 34using OpenSim.Region.Physics.Manager;
35using OpenSim.Region.Physics.OdePlugin.Meshing; 35//using OpenSim.Region.Physics.OdePlugin.Meshing;
36 36
37namespace OpenSim.Region.Physics.OdePlugin 37namespace OpenSim.Region.Physics.OdePlugin
38{ 38{
@@ -98,6 +98,8 @@ namespace OpenSim.Region.Physics.OdePlugin
98 public IntPtr space; 98 public IntPtr space;
99 public static Object OdeLock = new Object(); 99 public static Object OdeLock = new Object();
100 100
101 public IMesher mesher;
102
101 public OdeScene() 103 public OdeScene()
102 { 104 {
103 nearCallback = near; 105 nearCallback = near;
@@ -137,6 +139,12 @@ namespace OpenSim.Region.Physics.OdePlugin
137 139
138 } 140 }
139 141
142 public override void Initialise(IMesher meshmerizer)
143 {
144 mesher = meshmerizer;
145 }
146
147
140 // This function blatantly ripped off from BoxStack.cs 148 // This function blatantly ripped off from BoxStack.cs
141 private void near(IntPtr space, IntPtr g1, IntPtr g2) 149 private void near(IntPtr space, IntPtr g1, IntPtr g2)
142 { 150 {
@@ -308,7 +316,7 @@ namespace OpenSim.Region.Physics.OdePlugin
308 } 316 }
309 317
310 private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation, 318 private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation,
311 Mesh mesh, PrimitiveBaseShape pbs, bool isphysical) 319 IMesh mesh, PrimitiveBaseShape pbs, bool isphysical)
312 { 320 {
313 PhysicsVector pos = new PhysicsVector(); 321 PhysicsVector pos = new PhysicsVector();
314 pos.X = position.X; 322 pos.X = position.X;
@@ -409,11 +417,12 @@ namespace OpenSim.Region.Physics.OdePlugin
409 { 417 {
410 return this.AddPrimShape(primName, pbs, position, size, rotation, false); 418 return this.AddPrimShape(primName, pbs, position, size, rotation, false);
411 } 419 }
420
412 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position, 421 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
413 PhysicsVector size, Quaternion rotation, bool isPhysical) 422 PhysicsVector size, Quaternion rotation, bool isPhysical)
414 { 423 {
415 PhysicsActor result; 424 PhysicsActor result;
416 Mesh mesh = null; 425 IMesh mesh = null;
417 426
418 switch (pbs.ProfileShape) 427 switch (pbs.ProfileShape)
419 { 428 {
@@ -421,7 +430,7 @@ namespace OpenSim.Region.Physics.OdePlugin
421 /// support simple box & hollow box now; later, more shapes 430 /// support simple box & hollow box now; later, more shapes
422 if (needsMeshing(pbs)) 431 if (needsMeshing(pbs))
423 { 432 {
424 mesh = Meshmerizer.CreateMesh(primName, pbs, size); 433 mesh = mesher.CreateMesh(primName, pbs, size);
425 } 434 }
426 435
427 break; 436 break;
@@ -931,7 +940,7 @@ namespace OpenSim.Region.Physics.OdePlugin
931 private PhysicsVector _acceleration; 940 private PhysicsVector _acceleration;
932 public Quaternion _orientation; 941 public Quaternion _orientation;
933 942
934 private Mesh _mesh; 943 private IMesh _mesh;
935 private PrimitiveBaseShape _pbs; 944 private PrimitiveBaseShape _pbs;
936 private OdeScene _parent_scene; 945 private OdeScene _parent_scene;
937 public IntPtr prim_geom; 946 public IntPtr prim_geom;
@@ -953,7 +962,7 @@ namespace OpenSim.Region.Physics.OdePlugin
953 962
954 963
955 public OdePrim(String primName, OdeScene parent_scene, PhysicsVector pos, PhysicsVector size, 964 public OdePrim(String primName, OdeScene parent_scene, PhysicsVector pos, PhysicsVector size,
956 Quaternion rotation, Mesh mesh, PrimitiveBaseShape pbs, bool pisPhysical) 965 Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical)
957 { 966 {
958 967
959 968
@@ -1036,15 +1045,15 @@ namespace OpenSim.Region.Physics.OdePlugin
1036 Body = (IntPtr)0; 1045 Body = (IntPtr)0;
1037 } 1046 }
1038 } 1047 }
1039 public void setMesh(OdeScene parent_scene, Mesh mesh) 1048 public void setMesh(OdeScene parent_scene, IMesh mesh)
1040 { 1049 {
1041 //Kill Body so that mesh can re-make the geom 1050 //Kill Body so that mesh can re-make the geom
1042 if (IsPhysical && Body != (IntPtr)0) 1051 if (IsPhysical && Body != (IntPtr)0)
1043 { 1052 {
1044 disableBody(); 1053 disableBody();
1045 } 1054 }
1046 float[] vertexList = mesh.getVertexListAsFloat(); // Note, that vertextList is pinned in memory 1055 float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
1047 int[] indexList = mesh.getIndexListAsInt(); // Also pinned, needs release after usage 1056 int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
1048 int VertexCount = vertexList.GetLength(0)/3; 1057 int VertexCount = vertexList.GetLength(0)/3;
1049 int IndexCount = indexList.GetLength(0); 1058 int IndexCount = indexList.GetLength(0);
1050 1059
@@ -1169,7 +1178,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1169 1178
1170 1179
1171 // Don't need to re-enable body.. it's done in SetMesh 1180 // Don't need to re-enable body.. it's done in SetMesh
1172 Mesh mesh = Meshmerizer.CreateMesh(oldname, _pbs, _size); 1181 IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size);
1173 // createmesh returns null when it's a shape that isn't a cube. 1182 // createmesh returns null when it's a shape that isn't a cube.
1174 if (mesh != null) 1183 if (mesh != null)
1175 setMesh(_parent_scene, mesh); 1184 setMesh(_parent_scene, mesh);
@@ -1218,7 +1227,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1218 // Construction of new prim 1227 // Construction of new prim
1219 if (this._parent_scene.needsMeshing(_pbs)) 1228 if (this._parent_scene.needsMeshing(_pbs))
1220 { 1229 {
1221 Mesh mesh = Meshmerizer.CreateMesh(oldname, _pbs, _size); 1230 IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size);
1222 setMesh(_parent_scene, mesh); 1231 setMesh(_parent_scene, mesh);
1223 } else { 1232 } else {
1224 prim_geom = d.CreateBox(_parent_scene.space, _size.X, _size.Y, _size.Z); 1233 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 76121ae..7652372 100644
--- a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
+++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
@@ -84,6 +84,12 @@ namespace OpenSim.Region.Physics.PhysXPlugin
84 scene = mySdk.CreateScene(); 84 scene = mySdk.CreateScene();
85 } 85 }
86 86
87 public override void Initialise(IMesher meshmerizer)
88 {
89 // Does nothing right now
90 }
91
92
87 public override PhysicsActor AddAvatar(string avName, PhysicsVector position) 93 public override PhysicsActor AddAvatar(string avName, PhysicsVector position)
88 { 94 {
89 Vec3 pos = new Vec3(); 95 Vec3 pos = new Vec3();