aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs')
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs1855
1 files changed, 0 insertions, 1855 deletions
diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
deleted file mode 100644
index 8e9edac..0000000
--- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
+++ /dev/null
@@ -1,1855 +0,0 @@
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 OpenSimulator 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#region References
29
30using System;
31using System.Collections.Generic;
32using OpenMetaverse;
33using MonoXnaCompactMaths;
34using OpenSim.Framework;
35using OpenSim.Region.Physics.Manager;
36using XnaDevRu.BulletX;
37using XnaDevRu.BulletX.Dynamics;
38using Nini.Config;
39using Vector3 = MonoXnaCompactMaths.Vector3;
40using Quaternion = MonoXnaCompactMaths.Quaternion;
41
42#endregion
43
44namespace OpenSim.Region.Physics.BulletXPlugin
45{
46 /// <summary>
47 /// BulletXConversions are called now BulletXMaths
48 /// This Class converts objects and types for BulletX and give some operations
49 /// </summary>
50 public class BulletXMaths
51 {
52 //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
53
54 //Vector3
55 public static Vector3 PhysicsVectorToXnaVector3(OpenMetaverse.Vector3 physicsVector)
56 {
57 return new Vector3(physicsVector.X, physicsVector.Y, physicsVector.Z);
58 }
59
60 public static OpenMetaverse.Vector3 XnaVector3ToPhysicsVector(Vector3 xnaVector3)
61 {
62 return new OpenMetaverse.Vector3(xnaVector3.X, xnaVector3.Y, xnaVector3.Z);
63 }
64
65 //Quaternion
66 public static Quaternion QuaternionToXnaQuaternion(OpenMetaverse.Quaternion quaternion)
67 {
68 return new Quaternion(quaternion.X, quaternion.Y, quaternion.Z, quaternion.W);
69 }
70
71 public static OpenMetaverse.Quaternion XnaQuaternionToQuaternion(Quaternion xnaQuaternion)
72 {
73 return new OpenMetaverse.Quaternion(xnaQuaternion.W, xnaQuaternion.X, xnaQuaternion.Y, xnaQuaternion.Z);
74 }
75
76 //Next methods are extracted from XnaDevRu.BulletX(See 3rd party license):
77 //- SetRotation (class MatrixOperations)
78 //- GetRotation (class MatrixOperations)
79 //- GetElement (class MathHelper)
80 //- SetElement (class MathHelper)
81 internal static void SetRotation(ref Matrix m, Quaternion q)
82 {
83 float d = q.LengthSquared();
84 float s = 2f/d;
85 float xs = q.X*s, ys = q.Y*s, zs = q.Z*s;
86 float wx = q.W*xs, wy = q.W*ys, wz = q.W*zs;
87 float xx = q.X*xs, xy = q.X*ys, xz = q.X*zs;
88 float yy = q.Y*ys, yz = q.Y*zs, zz = q.Z*zs;
89 m = new Matrix(1 - (yy + zz), xy - wz, xz + wy, 0,
90 xy + wz, 1 - (xx + zz), yz - wx, 0,
91 xz - wy, yz + wx, 1 - (xx + yy), 0,
92 m.M41, m.M42, m.M43, 1);
93 }
94
95 internal static Quaternion GetRotation(Matrix m)
96 {
97 Quaternion q;
98
99 float trace = m.M11 + m.M22 + m.M33;
100
101 if (trace > 0)
102 {
103 float s = (float) Math.Sqrt(trace + 1);
104 q.W = s*0.5f;
105 s = 0.5f/s;
106
107 q.X = (m.M32 - m.M23)*s;
108 q.Y = (m.M13 - m.M31)*s;
109 q.Z = (m.M21 - m.M12)*s;
110 }
111 else
112 {
113 q.X = q.Y = q.Z = q.W = 0f;
114
115 int i = m.M11 < m.M22
116 ?
117 (m.M22 < m.M33 ? 2 : 1)
118 :
119 (m.M11 < m.M33 ? 2 : 0);
120 int j = (i + 1)%3;
121 int k = (i + 2)%3;
122
123 float s = (float) Math.Sqrt(GetElement(m, i, i) - GetElement(m, j, j) - GetElement(m, k, k) + 1);
124 SetElement(ref q, i, s*0.5f);
125 s = 0.5f/s;
126
127 q.W = (GetElement(m, k, j) - GetElement(m, j, k))*s;
128 SetElement(ref q, j, (GetElement(m, j, i) + GetElement(m, i, j))*s);
129 SetElement(ref q, k, (GetElement(m, k, i) + GetElement(m, i, k))*s);
130 }
131
132 return q;
133 }
134
135 internal static float SetElement(ref Quaternion q, int index, float value)
136 {
137 switch (index)
138 {
139 case 0:
140 q.X = value;
141 break;
142 case 1:
143 q.Y = value;
144 break;
145 case 2:
146 q.Z = value;
147 break;
148 case 3:
149 q.W = value;
150 break;
151 }
152
153 return 0;
154 }
155
156 internal static float GetElement(Matrix mat, int row, int col)
157 {
158 switch (row)
159 {
160 case 0:
161 switch (col)
162 {
163 case 0:
164 return mat.M11;
165 case 1:
166 return mat.M12;
167 case 2:
168 return mat.M13;
169 }
170 break;
171 case 1:
172 switch (col)
173 {
174 case 0:
175 return mat.M21;
176 case 1:
177 return mat.M22;
178 case 2:
179 return mat.M23;
180 }
181 break;
182 case 2:
183 switch (col)
184 {
185 case 0:
186 return mat.M31;
187 case 1:
188 return mat.M32;
189 case 2:
190 return mat.M33;
191 }
192 break;
193 }
194
195 return 0;
196 }
197 }
198
199 /// <summary>
200 /// PhysicsPlugin Class for BulletX
201 /// </summary>
202 public class BulletXPlugin : IPhysicsPlugin
203 {
204 private BulletXScene _mScene;
205
206 public BulletXPlugin()
207 {
208 }
209
210 public bool Init()
211 {
212 return true;
213 }
214
215 public PhysicsScene GetScene(string sceneIdentifier)
216 {
217 if (_mScene == null)
218 {
219 _mScene = new BulletXScene(sceneIdentifier);
220 }
221 return (_mScene);
222 }
223
224 public string GetName()
225 {
226 return ("modified_BulletX"); //Changed!! "BulletXEngine" To "modified_BulletX"
227 }
228
229 public void Dispose()
230 {
231 }
232 }
233
234
235 // Class to detect and debug collisions
236 // Mainly used for debugging purposes
237 internal class CollisionDispatcherLocal : CollisionDispatcher
238 {
239 private BulletXScene relatedScene;
240
241 public CollisionDispatcherLocal(BulletXScene s)
242 : base()
243 {
244 relatedScene = s;
245 }
246
247 public override bool NeedsCollision(CollisionObject bodyA, CollisionObject bodyB)
248 {
249 RigidBody rb;
250 BulletXCharacter bxcA = null;
251 BulletXPrim bxpA = null;
252 Type t = bodyA.GetType();
253 if (t == typeof (RigidBody))
254 {
255 rb = (RigidBody) bodyA;
256 relatedScene._characters.TryGetValue(rb, out bxcA);
257 relatedScene._prims.TryGetValue(rb, out bxpA);
258 }
259// String nameA;
260// if (bxcA != null)
261// nameA = bxcA._name;
262// else if (bxpA != null)
263// nameA = bxpA._name;
264// else
265// nameA = "null";
266
267
268
269 BulletXCharacter bxcB = null;
270 BulletXPrim bxpB = null;
271 t = bodyB.GetType();
272 if (t == typeof (RigidBody))
273 {
274 rb = (RigidBody) bodyB;
275 relatedScene._characters.TryGetValue(rb, out bxcB);
276 relatedScene._prims.TryGetValue(rb, out bxpB);
277 }
278
279// String nameB;
280// if (bxcB != null)
281// nameB = bxcB._name;
282// else if (bxpB != null)
283// nameB = bxpB._name;
284// else
285 // nameB = "null";
286 bool needsCollision;// = base.NeedsCollision(bodyA, bodyB);
287 int c1 = 3;
288 int c2 = 3;
289
290 ////////////////////////////////////////////////////////
291 //BulletX Mesh Collisions
292 //added by Jed zhu
293 //data: May 07,2005
294 ////////////////////////////////////////////////////////
295 #region BulletXMeshCollisions Fields
296
297
298 if (bxcA != null && bxpB != null)
299 c1 = Collision(bxcA, bxpB);
300 if (bxpA != null && bxcB != null)
301 c2 = Collision(bxcB, bxpA);
302 if (c1 < 2)
303 needsCollision = (c1 > 0) ? true : false;
304 else if (c2 < 2)
305 needsCollision = (c2 > 0) ? true : false;
306 else
307 needsCollision = base.NeedsCollision(bodyA, bodyB);
308
309
310 #endregion
311
312
313 //m_log.DebugFormat("[BulletX]: A collision was detected between {0} and {1} --> {2}", nameA, nameB,
314 //needsCollision);
315
316
317 return needsCollision;
318 }
319 //added by jed zhu
320 //calculas the collision between the Prim and Actor
321 //
322 private int Collision(BulletXCharacter actorA, BulletXPrim primB)
323 {
324 int[] indexBase;
325 Vector3[] vertexBase;
326 Vector3 vNormal;
327 // Vector3 vP1;
328 // Vector3 vP2;
329 // Vector3 vP3;
330 IMesh mesh = primB.GetMesh();
331
332 float fdistance;
333 if (primB == null)
334 return 3;
335 if (mesh == null)
336 return 2;
337 if (actorA == null)
338 return 3;
339
340 int iVertexCount = mesh.getVertexList().Count;
341 int iIndexCount = mesh.getIndexListAsInt().Length;
342 if (iVertexCount == 0)
343 return 3;
344 if (iIndexCount == 0)
345 return 3;
346 lock (BulletXScene.BulletXLock)
347 {
348 indexBase = mesh.getIndexListAsInt();
349 vertexBase = new Vector3[iVertexCount];
350
351 for (int i = 0; i < iVertexCount; i++)
352 {
353 OpenMetaverse.Vector3 v = mesh.getVertexList()[i];
354 if (v != null) // Note, null has special meaning. See meshing code for details
355 vertexBase[i] = BulletXMaths.PhysicsVectorToXnaVector3(v);
356 else
357 vertexBase[i] = Vector3.Zero;
358 }
359
360 for (int ix = 0; ix < iIndexCount; ix += 3)
361 {
362 int ia = indexBase[ix + 0];
363 int ib = indexBase[ix + 1];
364 int ic = indexBase[ix + 2];
365 //
366 Vector3 v1 = vertexBase[ib] - vertexBase[ia];
367 Vector3 v2 = vertexBase[ic] - vertexBase[ia];
368
369 Vector3.Cross(ref v1, ref v2, out vNormal);
370 Vector3.Normalize(ref vNormal, out vNormal);
371
372 fdistance = Vector3.Dot(vNormal, vertexBase[ia]) + 0.50f;
373 if (preCheckCollision(actorA, vNormal, fdistance) == 1)
374 {
375 if (CheckCollision(actorA, ia, ib, ic, vNormal, vertexBase) == 1)
376 {
377 //PhysicsVector v = actorA.Position;
378 //Vector3 v3 = BulletXMaths.PhysicsVectorToXnaVector3(v);
379 //Vector3 vp = vNormal * (fdistance - Vector3.Dot(vNormal, v3) + 0.2f);
380 //actorA.Position += BulletXMaths.XnaVector3ToPhysicsVector(vp);
381 return 1;
382 }
383 }
384 }
385 }
386
387
388 return 0;
389 }
390 //added by jed zhu
391 //return value 1: need second check
392 //return value 0: no need check
393
394 private int preCheckCollision(BulletXActor actA, Vector3 vNormal, float fDist)
395 {
396 float fstartSide;
397 OpenMetaverse.Vector3 v = actA.Position;
398 Vector3 v3 = BulletXMaths.PhysicsVectorToXnaVector3(v);
399
400 fstartSide = Vector3.Dot(vNormal, v3) - fDist;
401 if (fstartSide > 0) return 0;
402 else return 1;
403 }
404 //added by jed zhu
405 private int CheckCollision(BulletXActor actA, int ia, int ib, int ic, Vector3 vNormal, Vector3[] vertBase)
406 {
407 Vector3 perPlaneNormal;
408 float fPerPlaneDist;
409 OpenMetaverse.Vector3 v = actA.Position;
410 Vector3 v3 = BulletXMaths.PhysicsVectorToXnaVector3(v);
411 //check AB
412 Vector3 v1;
413 v1 = vertBase[ib] - vertBase[ia];
414 Vector3.Cross(ref vNormal, ref v1, out perPlaneNormal);
415 Vector3.Normalize(ref perPlaneNormal, out perPlaneNormal);
416
417 if (Vector3.Dot((vertBase[ic] - vertBase[ia]), perPlaneNormal) < 0)
418 perPlaneNormal = -perPlaneNormal;
419 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ia]) - 0.50f;
420
421
422
423 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) < 0)
424 return 0;
425 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ic]) + 0.50f;
426 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) > 0)
427 return 0;
428
429 //check BC
430
431 v1 = vertBase[ic] - vertBase[ib];
432 Vector3.Cross(ref vNormal, ref v1, out perPlaneNormal);
433 Vector3.Normalize(ref perPlaneNormal, out perPlaneNormal);
434
435 if (Vector3.Dot((vertBase[ia] - vertBase[ib]), perPlaneNormal) < 0)
436 perPlaneNormal = -perPlaneNormal;
437 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ib]) - 0.50f;
438
439
440 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) < 0)
441 return 0;
442 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ia]) + 0.50f;
443 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) > 0)
444 return 0;
445 //check CA
446 v1 = vertBase[ia] - vertBase[ic];
447 Vector3.Cross(ref vNormal, ref v1, out perPlaneNormal);
448 Vector3.Normalize(ref perPlaneNormal, out perPlaneNormal);
449
450 if (Vector3.Dot((vertBase[ib] - vertBase[ic]), perPlaneNormal) < 0)
451 perPlaneNormal = -perPlaneNormal;
452 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ic]) - 0.50f;
453
454
455 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) < 0)
456 return 0;
457 fPerPlaneDist = Vector3.Dot(perPlaneNormal, vertBase[ib]) + 0.50f;
458 if ((Vector3.Dot(perPlaneNormal, v3) - fPerPlaneDist) > 0)
459 return 0;
460
461 return 1;
462
463 }
464 }
465
466 /// <summary>
467 /// PhysicsScene Class for BulletX
468 /// </summary>
469 public class BulletXScene : PhysicsScene
470 {
471 #region BulletXScene Fields
472
473 public DiscreteDynamicsWorld ddWorld;
474 private CollisionDispatcher cDispatcher;
475 private OverlappingPairCache opCache;
476 private SequentialImpulseConstraintSolver sicSolver;
477 public static Object BulletXLock = new Object();
478
479 private const int minXY = 0;
480 private const int minZ = 0;
481 private const int maxXY = (int)Constants.RegionSize;
482 private const int maxZ = 4096;
483 private const int maxHandles = 32766; //Why? I don't know
484 private const float gravity = 9.8f;
485 private const float heightLevel0 = 77.0f;
486 private const float heightLevel1 = 200.0f;
487 private const float lowGravityFactor = 0.2f;
488 //OpenSim calls Simulate 10 times per seconds. So FPS = "Simulate Calls" * simulationSubSteps = 100 FPS
489 private const int simulationSubSteps = 10;
490 //private float[] _heightmap;
491 private BulletXPlanet _simFlatPlanet;
492 internal Dictionary<RigidBody, BulletXCharacter> _characters = new Dictionary<RigidBody, BulletXCharacter>();
493 internal Dictionary<RigidBody, BulletXPrim> _prims = new Dictionary<RigidBody, BulletXPrim>();
494
495 public IMesher mesher;
496 // private IConfigSource m_config;
497
498 // protected internal String identifier;
499
500 public BulletXScene(String sceneIdentifier)
501 {
502 //identifier = sceneIdentifier;
503 cDispatcher = new CollisionDispatcherLocal(this);
504 Vector3 worldMinDim = new Vector3((float)minXY, (float)minXY, (float)minZ);
505 Vector3 worldMaxDim = new Vector3((float)maxXY, (float)maxXY, (float)maxZ);
506 opCache = new AxisSweep3(worldMinDim, worldMaxDim, maxHandles);
507 sicSolver = new SequentialImpulseConstraintSolver();
508
509 lock (BulletXLock)
510 {
511 ddWorld = new DiscreteDynamicsWorld(cDispatcher, opCache, sicSolver);
512 ddWorld.Gravity = new Vector3(0, 0, -gravity);
513 }
514 //this._heightmap = new float[65536];
515 }
516
517 public static float Gravity
518 {
519 get { return gravity; }
520 }
521
522 public static float HeightLevel0
523 {
524 get { return heightLevel0; }
525 }
526
527 public static float HeightLevel1
528 {
529 get { return heightLevel1; }
530 }
531
532 public static float LowGravityFactor
533 {
534 get { return lowGravityFactor; }
535 }
536
537 public static int MaxXY
538 {
539 get { return maxXY; }
540 }
541
542 public static int MaxZ
543 {
544 get { return maxZ; }
545 }
546
547 private List<RigidBody> _forgottenRigidBodies = new List<RigidBody>();
548 internal string is_ex_message = "Can't remove rigidBody!: ";
549
550 #endregion
551
552 public BulletXScene()
553 {
554 cDispatcher = new CollisionDispatcherLocal(this);
555 Vector3 worldMinDim = new Vector3((float) minXY, (float) minXY, (float) minZ);
556 Vector3 worldMaxDim = new Vector3((float) maxXY, (float) maxXY, (float) maxZ);
557 opCache = new AxisSweep3(worldMinDim, worldMaxDim, maxHandles);
558 sicSolver = new SequentialImpulseConstraintSolver();
559
560 lock (BulletXLock)
561 {
562 ddWorld = new DiscreteDynamicsWorld(cDispatcher, opCache, sicSolver);
563 ddWorld.Gravity = new Vector3(0, 0, -gravity);
564 }
565 //this._heightmap = new float[65536];
566 }
567
568 public override void Initialise(IMesher meshmerizer, IConfigSource config)
569 {
570 mesher = meshmerizer;
571 // m_config = config;
572 }
573
574 public override void Dispose()
575 {
576
577 }
578
579 public override Dictionary<uint, float> GetTopColliders()
580 {
581 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>();
582 return returncolliders;
583 }
584
585 public override void SetWaterLevel(float baseheight)
586 {
587
588 }
589
590 public override PhysicsActor AddAvatar(string avName, OpenMetaverse.Vector3 position, OpenMetaverse.Vector3 size, bool isFlying)
591 {
592 OpenMetaverse.Vector3 pos = OpenMetaverse.Vector3.Zero;
593 pos.X = position.X;
594 pos.Y = position.Y;
595 pos.Z = position.Z + 20;
596 BulletXCharacter newAv = null;
597 lock (BulletXLock)
598 {
599 newAv = new BulletXCharacter(avName, this, pos);
600 _characters.Add(newAv.RigidBody, newAv);
601 }
602 newAv.Flying = isFlying;
603 return newAv;
604 }
605
606 public override void RemoveAvatar(PhysicsActor actor)
607 {
608 if (actor is BulletXCharacter)
609 {
610 lock (BulletXLock)
611 {
612 try
613 {
614 ddWorld.RemoveRigidBody(((BulletXCharacter) actor).RigidBody);
615 }
616 catch (Exception ex)
617 {
618 BulletXMessage(is_ex_message + ex.Message, true);
619 ((BulletXCharacter) actor).RigidBody.ActivationState = ActivationState.DisableSimulation;
620 AddForgottenRigidBody(((BulletXCharacter) actor).RigidBody);
621 }
622 _characters.Remove(((BulletXCharacter) actor).RigidBody);
623 }
624 GC.Collect();
625 }
626 }
627
628 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, OpenMetaverse.Vector3 position,
629 OpenMetaverse.Vector3 size, OpenMetaverse.Quaternion rotation, bool isPhysical, uint localid)
630 {
631 PhysicsActor result;
632
633 switch (pbs.ProfileShape)
634 {
635 case ProfileShape.Square:
636 /// support simple box & hollow box now; later, more shapes
637 if (pbs.ProfileHollow == 0)
638 {
639 result = AddPrim(primName, position, size, rotation, null, null, isPhysical);
640 }
641 else
642 {
643 IMesh mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical);
644 result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical);
645 }
646 break;
647
648 default:
649 result = AddPrim(primName, position, size, rotation, null, null, isPhysical);
650 break;
651 }
652
653 return result;
654 }
655
656 public PhysicsActor AddPrim(String name, OpenMetaverse.Vector3 position, OpenMetaverse.Vector3 size, OpenMetaverse.Quaternion rotation,
657 IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
658 {
659 BulletXPrim newPrim = null;
660 lock (BulletXLock)
661 {
662 newPrim = new BulletXPrim(name, this, position, size, rotation, mesh, pbs, isPhysical);
663 _prims.Add(newPrim.RigidBody, newPrim);
664 }
665 return newPrim;
666 }
667
668 public override void RemovePrim(PhysicsActor prim)
669 {
670 if (prim is BulletXPrim)
671 {
672 lock (BulletXLock)
673 {
674 try
675 {
676 ddWorld.RemoveRigidBody(((BulletXPrim) prim).RigidBody);
677 }
678 catch (Exception ex)
679 {
680 BulletXMessage(is_ex_message + ex.Message, true);
681 ((BulletXPrim) prim).RigidBody.ActivationState = ActivationState.DisableSimulation;
682 AddForgottenRigidBody(((BulletXPrim) prim).RigidBody);
683 }
684 _prims.Remove(((BulletXPrim) prim).RigidBody);
685 }
686 GC.Collect();
687 }
688 }
689
690 public override void AddPhysicsActorTaint(PhysicsActor prim)
691 {
692 }
693
694 public override float Simulate(float timeStep)
695 {
696 float fps = 0;
697 lock (BulletXLock)
698 {
699 //Try to remove garbage
700 RemoveForgottenRigidBodies();
701 //End of remove
702 MoveAPrimitives(timeStep);
703
704
705 fps = (timeStep*simulationSubSteps);
706
707 ddWorld.StepSimulation(timeStep, simulationSubSteps, timeStep);
708 //Extra Heightmap Validation: BulletX's HeightFieldTerrain somestimes doesn't work so fine.
709 ValidateHeightForAll();
710 //End heightmap validation.
711 UpdateKineticsForAll();
712 }
713 return fps;
714 }
715
716 private void MoveAPrimitives(float timeStep)
717 {
718 foreach (BulletXCharacter actor in _characters.Values)
719 {
720 actor.Move(timeStep);
721 }
722 }
723
724 private void ValidateHeightForAll()
725 {
726 float _height;
727 foreach (BulletXCharacter actor in _characters.Values)
728 {
729 //_height = HeightValue(actor.RigidBodyPosition);
730 _height = _simFlatPlanet.HeightValue(actor.RigidBodyPosition);
731 actor.ValidateHeight(_height);
732 //if (_simFlatPlanet.heightIsNotValid(actor.RigidBodyPosition, out _height)) actor.ValidateHeight(_height);
733 }
734 foreach (BulletXPrim prim in _prims.Values)
735 {
736 //_height = HeightValue(prim.RigidBodyPosition);
737 _height = _simFlatPlanet.HeightValue(prim.RigidBodyPosition);
738 prim.ValidateHeight(_height);
739 //if (_simFlatPlanet.heightIsNotValid(prim.RigidBodyPosition, out _height)) prim.ValidateHeight(_height);
740 }
741 //foreach (BulletXCharacter actor in _characters)
742 //{
743 // actor.ValidateHeight(0);
744 //}
745 //foreach (BulletXPrim prim in _prims)
746 //{
747 // prim.ValidateHeight(0);
748 //}
749 }
750
751 private void UpdateKineticsForAll()
752 {
753 //UpdatePosition > UpdateKinetics.
754 //Not only position will be updated, also velocity cause acceleration.
755 foreach (BulletXCharacter actor in _characters.Values)
756 {
757 actor.UpdateKinetics();
758 }
759 foreach (BulletXPrim prim in _prims.Values)
760 {
761 prim.UpdateKinetics();
762 }
763 //if (this._simFlatPlanet!=null) this._simFlatPlanet.Restore();
764 }
765
766 public override void GetResults()
767 {
768 }
769
770 public override bool IsThreaded
771 {
772 get
773 {
774 return (false); // for now we won't be multithreaded
775 }
776 }
777
778 public override void SetTerrain(float[] heightMap)
779 {
780 ////As the same as ODE, heightmap (x,y) must be swapped for BulletX
781 //for (int i = 0; i < 65536; i++)
782 //{
783 // // this._heightmap[i] = (double)heightMap[i];
784 // // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
785 // int x = i & 0xff;
786 // int y = i >> 8;
787 // this._heightmap[i] = heightMap[x * 256 + y];
788 //}
789
790 //float[] swappedHeightMap = new float[65536];
791 ////As the same as ODE, heightmap (x,y) must be swapped for BulletX
792 //for (int i = 0; i < 65536; i++)
793 //{
794 // // this._heightmap[i] = (double)heightMap[i];
795 // // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
796 // int x = i & 0xff;
797 // int y = i >> 8;
798 // swappedHeightMap[i] = heightMap[x * 256 + y];
799 //}
800 DeleteTerrain();
801 //There is a BulletXLock inside the constructor of BulletXPlanet
802 //this._simFlatPlanet = new BulletXPlanet(this, swappedHeightMap);
803 _simFlatPlanet = new BulletXPlanet(this, heightMap);
804 //this._heightmap = heightMap;
805 }
806
807 public override void DeleteTerrain()
808 {
809 if (_simFlatPlanet != null)
810 {
811 lock (BulletXLock)
812 {
813 try
814 {
815 ddWorld.RemoveRigidBody(_simFlatPlanet.RigidBody);
816 }
817 catch (Exception ex)
818 {
819 BulletXMessage(is_ex_message + ex.Message, true);
820 _simFlatPlanet.RigidBody.ActivationState = ActivationState.DisableSimulation;
821 AddForgottenRigidBody(_simFlatPlanet.RigidBody);
822 }
823 }
824 _simFlatPlanet = null;
825 GC.Collect();
826 BulletXMessage("Terrain erased!", false);
827 }
828
829
830
831 //this._heightmap = null;
832 }
833
834
835
836 internal void AddForgottenRigidBody(RigidBody forgottenRigidBody)
837 {
838 _forgottenRigidBodies.Add(forgottenRigidBody);
839 }
840
841 private void RemoveForgottenRigidBodies()
842 {
843 RigidBody forgottenRigidBody;
844 int nRigidBodies = _forgottenRigidBodies.Count;
845 for (int i = nRigidBodies - 1; i >= 0; i--)
846 {
847 forgottenRigidBody = _forgottenRigidBodies[i];
848 try
849 {
850 ddWorld.RemoveRigidBody(forgottenRigidBody);
851 _forgottenRigidBodies.Remove(forgottenRigidBody);
852 BulletXMessage("Forgotten Rigid Body Removed", false);
853 }
854 catch (Exception ex)
855 {
856 BulletXMessage("Can't remove forgottenRigidBody!: " + ex.Message, false);
857 }
858 }
859 GC.Collect();
860 }
861
862 internal static void BulletXMessage(string message, bool isWarning)
863 {
864 PhysicsPluginManager.PhysicsPluginMessage("[Modified BulletX]:\t" + message, isWarning);
865 }
866
867 //temp
868 //private float HeightValue(MonoXnaCompactMaths.Vector3 position)
869 //{
870 // int li_x, li_y;
871 // float height;
872 // li_x = (int)Math.Round(position.X); if (li_x < 0) li_x = 0;
873 // li_y = (int)Math.Round(position.Y); if (li_y < 0) li_y = 0;
874
875 // height = this._heightmap[li_y * 256 + li_x];
876 // if (height < 0) height = 0;
877 // else if (height > maxZ) height = maxZ;
878
879 // return height;
880 //}
881 }
882
883 /// <summary>
884 /// Generic Physics Actor for BulletX inherit from PhysicActor
885 /// </summary>
886 public class BulletXActor : PhysicsActor
887 {
888 protected bool flying = false;
889 protected bool _physical = false;
890 protected OpenMetaverse.Vector3 _position;
891 protected OpenMetaverse.Vector3 _velocity;
892 protected OpenMetaverse.Vector3 _size;
893 protected OpenMetaverse.Vector3 _acceleration;
894 protected OpenMetaverse.Quaternion _orientation;
895 protected OpenMetaverse.Vector3 m_rotationalVelocity;
896 protected RigidBody rigidBody;
897 protected int m_PhysicsActorType;
898 private Boolean iscolliding = false;
899 internal string _name;
900
901 public BulletXActor(String name)
902 {
903 _name = name;
904 }
905
906 public override bool Stopped
907 {
908 get { return false; }
909 }
910
911 public override OpenMetaverse.Vector3 Position
912 {
913 get { return _position; }
914 set
915 {
916 lock (BulletXScene.BulletXLock)
917 {
918 _position = value;
919 Translate();
920 }
921 }
922 }
923
924 public override OpenMetaverse.Vector3 RotationalVelocity
925 {
926 get { return m_rotationalVelocity; }
927 set { m_rotationalVelocity = value; }
928 }
929
930 public override OpenMetaverse.Vector3 Velocity
931 {
932 get { return _velocity; }
933 set
934 {
935 lock (BulletXScene.BulletXLock)
936 {
937 //Static objects don' have linear velocity
938 if (_physical)
939 {
940 _velocity = value;
941 Speed();
942 }
943 else
944 {
945 _velocity = OpenMetaverse.Vector3.Zero;
946 }
947 }
948 }
949 }
950 public override float CollisionScore
951 {
952 get { return 0f; }
953 set { }
954 }
955 public override OpenMetaverse.Vector3 Size
956 {
957 get { return _size; }
958 set
959 {
960 lock (BulletXScene.BulletXLock)
961 {
962 _size = value;
963 }
964 }
965 }
966
967 public override OpenMetaverse.Vector3 Force
968 {
969 get { return OpenMetaverse.Vector3.Zero; }
970 set { return; }
971 }
972
973 public override int VehicleType
974 {
975 get { return 0; }
976 set { return; }
977 }
978
979 public override void VehicleFloatParam(int param, float value)
980 {
981
982 }
983
984 public override void VehicleVectorParam(int param, OpenMetaverse.Vector3 value)
985 {
986
987 }
988
989 public override void VehicleRotationParam(int param, OpenMetaverse.Quaternion rotation)
990 {
991
992 }
993
994 public override void VehicleFlags(int param, bool remove)
995 {
996
997 }
998
999 public override void SetVolumeDetect(int param)
1000 {
1001
1002 }
1003
1004 public override OpenMetaverse.Vector3 CenterOfMass
1005 {
1006 get { return OpenMetaverse.Vector3.Zero; }
1007 }
1008
1009 public override OpenMetaverse.Vector3 GeometricCenter
1010 {
1011 get { return OpenMetaverse.Vector3.Zero; }
1012 }
1013
1014 public override PrimitiveBaseShape Shape
1015 {
1016 set { return; }
1017 }
1018
1019 public override bool SetAlwaysRun
1020 {
1021 get { return false; }
1022 set { return; }
1023 }
1024
1025 public override OpenMetaverse.Vector3 Acceleration
1026 {
1027 get { return _acceleration; }
1028 }
1029
1030 public override OpenMetaverse.Quaternion Orientation
1031 {
1032 get { return _orientation; }
1033 set
1034 {
1035 lock (BulletXScene.BulletXLock)
1036 {
1037 _orientation = value;
1038 ReOrient();
1039 }
1040 }
1041 }
1042 public override void link(PhysicsActor obj)
1043 {
1044
1045 }
1046
1047 public override void delink()
1048 {
1049
1050 }
1051
1052 public override void LockAngularMotion(OpenMetaverse.Vector3 axis)
1053 {
1054
1055 }
1056
1057 public override float Mass
1058 {
1059 get { return ActorMass; }
1060 }
1061
1062 public virtual float ActorMass
1063 {
1064 get { return 0; }
1065 }
1066
1067 public override int PhysicsActorType
1068 {
1069 get { return (int) m_PhysicsActorType; }
1070 set { m_PhysicsActorType = value; }
1071 }
1072
1073 public RigidBody RigidBody
1074 {
1075 get { return rigidBody; }
1076 }
1077
1078 public Vector3 RigidBodyPosition
1079 {
1080 get { return rigidBody.CenterOfMassPosition; }
1081 }
1082
1083 public override bool IsPhysical
1084 {
1085 get { return _physical; }
1086 set { _physical = value; }
1087 }
1088
1089 public override bool Flying
1090 {
1091 get { return flying; }
1092 set { flying = value; }
1093 }
1094
1095 public override bool ThrottleUpdates
1096 {
1097 get { return false; }
1098 set { return; }
1099 }
1100
1101 public override bool IsColliding
1102 {
1103 get { return iscolliding; }
1104 set { iscolliding = value; }
1105 }
1106
1107 public override bool CollidingGround
1108 {
1109 get { return false; }
1110 set { return; }
1111 }
1112
1113 public override bool CollidingObj
1114 {
1115 get { return false; }
1116 set { return; }
1117 }
1118
1119 public override uint LocalID
1120 {
1121 set { return; }
1122 }
1123
1124 public override bool Grabbed
1125 {
1126 set { return; }
1127 }
1128
1129 public override bool Selected
1130 {
1131 set { return; }
1132 }
1133
1134 public override float Buoyancy
1135 {
1136 get { return 0f; }
1137 set { return; }
1138 }
1139
1140 public override bool FloatOnWater
1141 {
1142 set { return; }
1143 }
1144
1145 public virtual void SetAcceleration(OpenMetaverse.Vector3 accel)
1146 {
1147 lock (BulletXScene.BulletXLock)
1148 {
1149 _acceleration = accel;
1150 }
1151 }
1152
1153 public override bool Kinematic
1154 {
1155 get { return false; }
1156 set { }
1157 }
1158
1159 public override void AddForce(OpenMetaverse.Vector3 force, bool pushforce)
1160 {
1161 }
1162 public override OpenMetaverse.Vector3 Torque
1163 {
1164 get { return OpenMetaverse.Vector3.Zero; }
1165 set { return; }
1166 }
1167 public override void AddAngularForce(OpenMetaverse.Vector3 force, bool pushforce)
1168 {
1169 }
1170
1171 public override void SetMomentum(OpenMetaverse.Vector3 momentum)
1172 {
1173 }
1174
1175 internal virtual void ValidateHeight(float heighmapPositionValue)
1176 {
1177 }
1178
1179 internal virtual void UpdateKinetics()
1180 {
1181 }
1182
1183 #region Methods for updating values of RigidBody
1184
1185 protected internal void Translate()
1186 {
1187 Translate(_position);
1188 }
1189
1190 protected internal void Translate(OpenMetaverse.Vector3 _newPos)
1191 {
1192 Vector3 _translation;
1193 _translation = BulletXMaths.PhysicsVectorToXnaVector3(_newPos) - rigidBody.CenterOfMassPosition;
1194 rigidBody.Translate(_translation);
1195 }
1196
1197 protected internal void Speed()
1198 {
1199 Speed(_velocity);
1200 }
1201
1202 protected internal void Speed(OpenMetaverse.Vector3 _newSpeed)
1203 {
1204 Vector3 _speed;
1205 _speed = BulletXMaths.PhysicsVectorToXnaVector3(_newSpeed);
1206 rigidBody.LinearVelocity = _speed;
1207 }
1208
1209 protected internal void ReOrient()
1210 {
1211 ReOrient(_orientation);
1212 }
1213
1214 protected internal void ReOrient(OpenMetaverse.Quaternion _newOrient)
1215 {
1216 Quaternion _newOrientation;
1217 _newOrientation = BulletXMaths.QuaternionToXnaQuaternion(_newOrient);
1218 Matrix _comTransform = rigidBody.CenterOfMassTransform;
1219 BulletXMaths.SetRotation(ref _comTransform, _newOrientation);
1220 rigidBody.CenterOfMassTransform = _comTransform;
1221 }
1222
1223 protected internal void ReSize()
1224 {
1225 ReSize(_size);
1226 }
1227
1228 protected internal virtual void ReSize(OpenMetaverse.Vector3 _newSize)
1229 {
1230 }
1231
1232 public virtual void ScheduleTerseUpdate()
1233 {
1234 base.RequestPhysicsterseUpdate();
1235 }
1236
1237 #endregion
1238
1239 public override void CrossingFailure()
1240 {
1241
1242 }
1243 public override OpenMetaverse.Vector3 PIDTarget { set { return; } }
1244 public override bool PIDActive { set { return; } }
1245 public override float PIDTau { set { return; } }
1246
1247 public override float PIDHoverHeight { set { return; } }
1248 public override bool PIDHoverActive { set { return; } }
1249 public override PIDHoverType PIDHoverType { set { return; } }
1250 public override float PIDHoverTau { set { return; } }
1251
1252 public override OpenMetaverse.Quaternion APIDTarget
1253 {
1254 set { return; }
1255 }
1256
1257 public override bool APIDActive
1258 {
1259 set { return; }
1260 }
1261
1262 public override float APIDStrength
1263 {
1264 set { return; }
1265 }
1266
1267 public override float APIDDamping
1268 {
1269 set { return; }
1270 }
1271
1272
1273 public override void SubscribeEvents(int ms)
1274 {
1275
1276 }
1277 public override void UnSubscribeEvents()
1278 {
1279
1280 }
1281 public override bool SubscribedEvents()
1282 {
1283 return false;
1284 }
1285 }
1286
1287 /// <summary>
1288 /// PhysicsActor Character Class for BulletX
1289 /// </summary>
1290 public class BulletXCharacter : BulletXActor
1291 {
1292 public BulletXCharacter(BulletXScene parent_scene, OpenMetaverse.Vector3 pos)
1293 : this(String.Empty, parent_scene, pos)
1294 {
1295 }
1296
1297 public BulletXCharacter(String avName, BulletXScene parent_scene, OpenMetaverse.Vector3 pos)
1298 : this(avName, parent_scene, pos, OpenMetaverse.Vector3.Zero, OpenMetaverse.Vector3.Zero, OpenMetaverse.Vector3.Zero,
1299 OpenMetaverse.Quaternion.Identity)
1300 {
1301 }
1302
1303 public BulletXCharacter(String avName, BulletXScene parent_scene, OpenMetaverse.Vector3 pos, OpenMetaverse.Vector3 velocity,
1304 OpenMetaverse.Vector3 size, OpenMetaverse.Vector3 acceleration, OpenMetaverse.Quaternion orientation)
1305 : base(avName)
1306 {
1307 //This fields will be removed. They're temporal
1308 float _sizeX = 0.5f;
1309 float _sizeY = 0.5f;
1310 float _sizeZ = 1.6f;
1311 //.
1312 _position = pos;
1313 _velocity = velocity;
1314 _size = size;
1315 //---
1316 _size.X = _sizeX;
1317 _size.Y = _sizeY;
1318 _size.Z = _sizeZ;
1319 //.
1320 _acceleration = acceleration;
1321 _orientation = orientation;
1322 _physical = true;
1323
1324 float _mass = 50.0f; //This depends of avatar's dimensions
1325 //For RigidBody Constructor. The next values might change
1326 float _linearDamping = 0.0f;
1327 float _angularDamping = 0.0f;
1328 float _friction = 0.5f;
1329 float _restitution = 0.0f;
1330 Matrix _startTransform = Matrix.Identity;
1331 Matrix _centerOfMassOffset = Matrix.Identity;
1332 lock (BulletXScene.BulletXLock)
1333 {
1334 _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);
1335 //CollisionShape _collisionShape = new BoxShape(new MonoXnaCompactMaths.Vector3(1.0f, 1.0f, 1.60f));
1336 //For now, like ODE, collisionShape = sphere of radious = 1.0
1337 CollisionShape _collisionShape = new SphereShape(1.0f);
1338 DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
1339 Vector3 _localInertia = new Vector3();
1340 _collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0
1341 rigidBody =
1342 new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping,
1343 _friction, _restitution);
1344 //rigidBody.ActivationState = ActivationState.DisableDeactivation;
1345 //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
1346 Vector3 _vDebugTranslation;
1347 _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition;
1348 rigidBody.Translate(_vDebugTranslation);
1349 parent_scene.ddWorld.AddRigidBody(rigidBody);
1350 }
1351 }
1352
1353 public override int PhysicsActorType
1354 {
1355 get { return (int) ActorTypes.Agent; }
1356 set { return; }
1357 }
1358
1359 public override OpenMetaverse.Vector3 Position
1360 {
1361 get { return base.Position; }
1362 set { base.Position = value; }
1363 }
1364
1365 public override OpenMetaverse.Vector3 Velocity
1366 {
1367 get { return base.Velocity; }
1368 set { base.Velocity = value; }
1369 }
1370
1371 public override OpenMetaverse.Vector3 Size
1372 {
1373 get { return base.Size; }
1374 set { base.Size = value; }
1375 }
1376
1377 public override OpenMetaverse.Vector3 Acceleration
1378 {
1379 get { return base.Acceleration; }
1380 }
1381
1382 public override OpenMetaverse.Quaternion Orientation
1383 {
1384 get { return base.Orientation; }
1385 set { base.Orientation = value; }
1386 }
1387
1388 public override bool Flying
1389 {
1390 get { return base.Flying; }
1391 set { base.Flying = value; }
1392 }
1393
1394 public override bool IsColliding
1395 {
1396 get { return base.IsColliding; }
1397 set { base.IsColliding = value; }
1398 }
1399
1400 public override bool Kinematic
1401 {
1402 get { return base.Kinematic; }
1403 set { base.Kinematic = value; }
1404 }
1405
1406 public override void SetAcceleration(OpenMetaverse.Vector3 accel)
1407 {
1408 base.SetAcceleration(accel);
1409 }
1410
1411 public override void AddForce(OpenMetaverse.Vector3 force, bool pushforce)
1412 {
1413 base.AddForce(force, pushforce);
1414 }
1415
1416 public override void SetMomentum(OpenMetaverse.Vector3 momentum)
1417 {
1418 base.SetMomentum(momentum);
1419 }
1420
1421 internal void Move(float timeStep)
1422 {
1423 Vector3 vec = new Vector3();
1424 //At this point it's supossed that:
1425 //_velocity == rigidBody.LinearVelocity
1426 vec.X = _velocity.X;
1427 vec.Y = _velocity.Y;
1428 vec.Z = _velocity.Z;
1429 if ((vec.X != 0.0f) || (vec.Y != 0.0f) || (vec.Z != 0.0f)) rigidBody.Activate();
1430 if (flying)
1431 {
1432 //Antigravity with movement
1433 if (_position.Z <= BulletXScene.HeightLevel0)
1434 {
1435 vec.Z += BulletXScene.Gravity*timeStep;
1436 }
1437 //Lowgravity with movement
1438 else if ((_position.Z > BulletXScene.HeightLevel0)
1439 && (_position.Z <= BulletXScene.HeightLevel1))
1440 {
1441 vec.Z += BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor);
1442 }
1443 //Lowgravity with...
1444 else if (_position.Z > BulletXScene.HeightLevel1)
1445 {
1446 if (vec.Z > 0) //no movement
1447 vec.Z = BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor);
1448 else
1449 vec.Z += BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor);
1450 }
1451 }
1452 rigidBody.LinearVelocity = vec;
1453 }
1454
1455 //This validation is very basic
1456 internal override void ValidateHeight(float heighmapPositionValue)
1457 {
1458 if (rigidBody.CenterOfMassPosition.Z < heighmapPositionValue + _size.Z/2.0f)
1459 {
1460 Matrix m = rigidBody.WorldTransform;
1461 Vector3 v3 = m.Translation;
1462 v3.Z = heighmapPositionValue + _size.Z/2.0f;
1463 m.Translation = v3;
1464 rigidBody.WorldTransform = m;
1465 //When an Avie touch the ground it's vertical velocity it's reduced to ZERO
1466 Speed(new OpenMetaverse.Vector3(rigidBody.LinearVelocity.X, rigidBody.LinearVelocity.Y, 0.0f));
1467 }
1468 }
1469
1470 internal override void UpdateKinetics()
1471 {
1472 _position = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition);
1473 _velocity = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.LinearVelocity);
1474 //Orientation it seems that it will be the default.
1475 ReOrient();
1476 }
1477 }
1478
1479 /// <summary>
1480 /// PhysicsActor Prim Class for BulletX
1481 /// </summary>
1482 public class BulletXPrim : BulletXActor
1483 {
1484 //Density it will depends of material.
1485 //For now all prims have the same density, all prims are made of water. Be water my friend! :D
1486 private const float _density = 1000.0f;
1487 private BulletXScene _parent_scene;
1488 private OpenMetaverse.Vector3 m_prev_position;
1489 private bool m_lastUpdateSent = false;
1490 //added by jed zhu
1491 private IMesh _mesh;
1492 public IMesh GetMesh() { return _mesh; }
1493
1494
1495
1496 public BulletXPrim(String primName, BulletXScene parent_scene, OpenMetaverse.Vector3 pos, OpenMetaverse.Vector3 size,
1497 OpenMetaverse.Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
1498 : this(
1499 primName, parent_scene, pos, OpenMetaverse.Vector3.Zero, size, OpenMetaverse.Vector3.Zero, rotation, mesh, pbs,
1500 isPhysical)
1501 {
1502 }
1503
1504 public BulletXPrim(String primName, BulletXScene parent_scene, OpenMetaverse.Vector3 pos, OpenMetaverse.Vector3 velocity,
1505 OpenMetaverse.Vector3 size,
1506 OpenMetaverse.Vector3 acceleration, OpenMetaverse.Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs,
1507 bool isPhysical)
1508 : base(primName)
1509 {
1510 if ((size.X == 0) || (size.Y == 0) || (size.Z == 0))
1511 throw new Exception("Size 0");
1512 if (OpenMetaverse.Quaternion.Normalize(rotation).Length() == 0f)
1513 rotation = OpenMetaverse.Quaternion.Identity;
1514
1515 _position = pos;
1516 _physical = isPhysical;
1517 _velocity = _physical ? velocity : OpenMetaverse.Vector3.Zero;
1518 _size = size;
1519 _acceleration = acceleration;
1520 _orientation = rotation;
1521
1522 _parent_scene = parent_scene;
1523
1524 CreateRigidBody(parent_scene, mesh, pos, size);
1525 }
1526
1527 public override int PhysicsActorType
1528 {
1529 get { return (int) ActorTypes.Prim; }
1530 set { return; }
1531 }
1532
1533 public override OpenMetaverse.Vector3 Position
1534 {
1535 get { return base.Position; }
1536 set { base.Position = value; }
1537 }
1538
1539 public override OpenMetaverse.Vector3 Velocity
1540 {
1541 get { return base.Velocity; }
1542 set { base.Velocity = value; }
1543 }
1544
1545 public override OpenMetaverse.Vector3 Size
1546 {
1547 get { return _size; }
1548 set
1549 {
1550 lock (BulletXScene.BulletXLock)
1551 {
1552 _size = value;
1553 ReSize();
1554 }
1555 }
1556 }
1557
1558 public override OpenMetaverse.Vector3 Acceleration
1559 {
1560 get { return base.Acceleration; }
1561 }
1562
1563 public override OpenMetaverse.Quaternion Orientation
1564 {
1565 get { return base.Orientation; }
1566 set { base.Orientation = value; }
1567 }
1568
1569 public override float ActorMass
1570 {
1571 get
1572 {
1573 //For now all prims are boxes
1574 return (_physical ? 1 : 0)*_density*_size.X*_size.Y*_size.Z;
1575 }
1576 }
1577
1578 public override bool IsPhysical
1579 {
1580 get { return base.IsPhysical; }
1581 set
1582 {
1583 base.IsPhysical = value;
1584 if (value)
1585 {
1586 //---
1587 PhysicsPluginManager.PhysicsPluginMessage("Physical - Recreate", true);
1588 //---
1589 ReCreateRigidBody(_size);
1590 }
1591 else
1592 {
1593 //---
1594 PhysicsPluginManager.PhysicsPluginMessage("Physical - SetMassProps", true);
1595 //---
1596 rigidBody.SetMassProps(Mass, new Vector3());
1597 }
1598 }
1599 }
1600
1601 public override bool Flying
1602 {
1603 get { return base.Flying; }
1604 set { base.Flying = value; }
1605 }
1606
1607 public override bool IsColliding
1608 {
1609 get { return base.IsColliding; }
1610 set { base.IsColliding = value; }
1611 }
1612
1613 public override bool Kinematic
1614 {
1615 get { return base.Kinematic; }
1616 set { base.Kinematic = value; }
1617 }
1618
1619 public override void SetAcceleration(OpenMetaverse.Vector3 accel)
1620 {
1621 lock (BulletXScene.BulletXLock)
1622 {
1623 _acceleration = accel;
1624 }
1625 }
1626
1627 public override void AddForce(OpenMetaverse.Vector3 force, bool pushforce)
1628 {
1629 base.AddForce(force,pushforce);
1630 }
1631
1632 public override void SetMomentum(OpenMetaverse.Vector3 momentum)
1633 {
1634 base.SetMomentum(momentum);
1635 }
1636
1637 internal override void ValidateHeight(float heighmapPositionValue)
1638 {
1639 if (rigidBody.CenterOfMassPosition.Z < heighmapPositionValue + _size.Z/2.0f)
1640 {
1641 Matrix m = rigidBody.WorldTransform;
1642 Vector3 v3 = m.Translation;
1643 v3.Z = heighmapPositionValue + _size.Z/2.0f;
1644 m.Translation = v3;
1645 rigidBody.WorldTransform = m;
1646 //When a Prim touch the ground it's vertical velocity it's reduced to ZERO
1647 //Static objects don't have linear velocity
1648 if (_physical)
1649 Speed(new OpenMetaverse.Vector3(rigidBody.LinearVelocity.X, rigidBody.LinearVelocity.Y, 0.0f));
1650 }
1651 }
1652
1653 internal override void UpdateKinetics()
1654 {
1655 if (_physical) //Updates properties. Prim updates its properties physically
1656 {
1657 _position = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition);
1658
1659 _velocity = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.LinearVelocity);
1660 _orientation = BulletXMaths.XnaQuaternionToQuaternion(rigidBody.Orientation);
1661
1662 if ((Math.Abs(m_prev_position.X - _position.X) < 0.03)
1663 && (Math.Abs(m_prev_position.Y - _position.Y) < 0.03)
1664 && (Math.Abs(m_prev_position.Z - _position.Z) < 0.03))
1665 {
1666 if (!m_lastUpdateSent)
1667 {
1668 _velocity = OpenMetaverse.Vector3.Zero;
1669 base.ScheduleTerseUpdate();
1670 m_lastUpdateSent = true;
1671 }
1672 }
1673 else
1674 {
1675 m_lastUpdateSent = false;
1676 base.ScheduleTerseUpdate();
1677 }
1678 m_prev_position = _position;
1679 }
1680 else //Doesn't updates properties. That's a cancel
1681 {
1682 Translate();
1683 //Speed(); //<- Static objects don't have linear velocity
1684 ReOrient();
1685 }
1686 }
1687
1688 #region Methods for updating values of RigidBody
1689
1690 protected internal void CreateRigidBody(BulletXScene parent_scene, IMesh mesh, OpenMetaverse.Vector3 pos,
1691 OpenMetaverse.Vector3 size)
1692 {
1693 //For RigidBody Constructor. The next values might change
1694 float _linearDamping = 0.0f;
1695 float _angularDamping = 0.0f;
1696 float _friction = 1.0f;
1697 float _restitution = 0.0f;
1698 Matrix _startTransform = Matrix.Identity;
1699 Matrix _centerOfMassOffset = Matrix.Identity;
1700 //added by jed zhu
1701 _mesh = mesh;
1702
1703 lock (BulletXScene.BulletXLock)
1704 {
1705 _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);
1706 //For now all prims are boxes
1707 CollisionShape _collisionShape;
1708 if (mesh == null)
1709 {
1710 _collisionShape = new BoxShape(BulletXMaths.PhysicsVectorToXnaVector3(size)/2.0f);
1711 }
1712 else
1713 {
1714 int iVertexCount = mesh.getVertexList().Count;
1715 int[] indices = mesh.getIndexListAsInt();
1716 Vector3[] v3Vertices = new Vector3[iVertexCount];
1717 for (int i = 0; i < iVertexCount; i++)
1718 {
1719 OpenMetaverse.Vector3 v = mesh.getVertexList()[i];
1720 if (v != null) // Note, null has special meaning. See meshing code for details
1721 v3Vertices[i] = BulletXMaths.PhysicsVectorToXnaVector3(v);
1722 else
1723 v3Vertices[i] = Vector3.Zero;
1724 }
1725 TriangleIndexVertexArray triMesh = new TriangleIndexVertexArray(indices, v3Vertices);
1726
1727 _collisionShape = new TriangleMeshShape(triMesh);
1728 }
1729 DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
1730 Vector3 _localInertia = new Vector3();
1731 if (_physical) _collisionShape.CalculateLocalInertia(Mass, out _localInertia); //Always when mass > 0
1732 rigidBody =
1733 new RigidBody(Mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping,
1734 _friction, _restitution);
1735 //rigidBody.ActivationState = ActivationState.DisableDeactivation;
1736 //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
1737 Vector3 _vDebugTranslation;
1738 _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition;
1739 rigidBody.Translate(_vDebugTranslation);
1740 //---
1741 parent_scene.ddWorld.AddRigidBody(rigidBody);
1742 }
1743 }
1744
1745 protected internal void ReCreateRigidBody(OpenMetaverse.Vector3 size)
1746 {
1747 //There is a bug when trying to remove a rigidBody that is colliding with something..
1748 try
1749 {
1750 _parent_scene.ddWorld.RemoveRigidBody(rigidBody);
1751 }
1752 catch (Exception ex)
1753 {
1754 BulletXScene.BulletXMessage(_parent_scene.is_ex_message + ex.Message, true);
1755 rigidBody.ActivationState = ActivationState.DisableSimulation;
1756 _parent_scene.AddForgottenRigidBody(rigidBody);
1757 }
1758 CreateRigidBody(_parent_scene, null, _position, size);
1759 // Note, null for the meshing definitely is wrong. It's here for the moment to apease the compiler
1760 if (_physical) Speed(); //Static objects don't have linear velocity
1761 ReOrient();
1762 GC.Collect();
1763 }
1764
1765 protected internal override void ReSize(OpenMetaverse.Vector3 _newSize)
1766 {
1767 //I wonder to know how to resize with a simple instruction in BulletX. It seems that for now there isn't
1768 //so i have to do it manually. That's recreating rigidbody
1769 ReCreateRigidBody(_newSize);
1770 }
1771
1772 #endregion
1773 }
1774
1775 /// <summary>
1776 /// This Class manage a HeighField as a RigidBody. This is for to be added in the BulletXScene
1777 /// </summary>
1778 internal class BulletXPlanet
1779 {
1780 private OpenMetaverse.Vector3 _staticPosition;
1781// private Vector3 _staticVelocity;
1782// private OpenMetaverse.Quaternion _staticOrientation;
1783 private float _mass;
1784 // private BulletXScene _parentscene;
1785 internal float[] _heightField;
1786 private RigidBody _flatPlanet;
1787
1788 internal RigidBody RigidBody
1789 {
1790 get { return _flatPlanet; }
1791 }
1792
1793 internal BulletXPlanet(BulletXScene parent_scene, float[] heightField)
1794 {
1795 _staticPosition = new OpenMetaverse.Vector3(BulletXScene.MaxXY / 2, BulletXScene.MaxXY / 2, 0);
1796// _staticVelocity = new PhysicsVector();
1797// _staticOrientation = OpenMetaverse.Quaternion.Identity;
1798 _mass = 0; //No active
1799 // _parentscene = parent_scene;
1800 _heightField = heightField;
1801
1802 float _linearDamping = 0.0f;
1803 float _angularDamping = 0.0f;
1804 float _friction = 0.5f;
1805 float _restitution = 0.0f;
1806 Matrix _startTransform = Matrix.Identity;
1807 Matrix _centerOfMassOffset = Matrix.Identity;
1808
1809 lock (BulletXScene.BulletXLock)
1810 {
1811 try
1812 {
1813 _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(_staticPosition);
1814 CollisionShape _collisionShape =
1815 new HeightfieldTerrainShape(BulletXScene.MaxXY, BulletXScene.MaxXY, _heightField,
1816 (float) BulletXScene.MaxZ, 2, true, false);
1817 DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
1818 Vector3 _localInertia = new Vector3();
1819 //_collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0
1820 _flatPlanet =
1821 new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping,
1822 _angularDamping, _friction, _restitution);
1823 //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
1824 Vector3 _vDebugTranslation;
1825 _vDebugTranslation = _startTransform.Translation - _flatPlanet.CenterOfMassPosition;
1826 _flatPlanet.Translate(_vDebugTranslation);
1827 parent_scene.ddWorld.AddRigidBody(_flatPlanet);
1828 }
1829 catch (Exception ex)
1830 {
1831 BulletXScene.BulletXMessage(ex.Message, true);
1832 }
1833 }
1834 BulletXScene.BulletXMessage("BulletXPlanet created.", false);
1835 }
1836
1837 internal float HeightValue(Vector3 position)
1838 {
1839 int li_x, li_y;
1840 float height;
1841 li_x = (int) Math.Round(position.X);
1842 if (li_x < 0) li_x = 0;
1843 if (li_x >= BulletXScene.MaxXY) li_x = BulletXScene.MaxXY - 1;
1844 li_y = (int) Math.Round(position.Y);
1845 if (li_y < 0) li_y = 0;
1846 if (li_y >= BulletXScene.MaxXY) li_y = BulletXScene.MaxXY - 1;
1847
1848 height = ((HeightfieldTerrainShape) _flatPlanet.CollisionShape).getHeightFieldValue(li_x, li_y);
1849 if (height < 0) height = 0;
1850 else if (height > BulletXScene.MaxZ) height = BulletXScene.MaxZ;
1851
1852 return height;
1853 }
1854 }
1855}