aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs464
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs13
-rw-r--r--ThirdPartyLicenses/BulletLicense.txt17
-rw-r--r--bin/Modified.XnaDevRu.BulletX.dllbin208896 -> 208896 bytes
-rw-r--r--bin/MonoXnaCompactMaths.dllbin36864 -> 36864 bytes
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX.suobin138240 -> 138240 bytes
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionShapes/HeightfieldTerrainShape.cs360
-rw-r--r--libraries/ModifiedBulletX/ModifiedBulletX/Modified.XnaDevRu.BulletX.csproj1
-rw-r--r--libraries/ModifiedBulletX/MonoXnaCompactMaths/Matrix.cs11
-rw-r--r--libraries/ModifiedBulletX/MonoXnaCompactMaths/Quaternion.cs91
10 files changed, 853 insertions, 104 deletions
diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
index af13d02..705eb38 100644
--- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
+++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
@@ -30,19 +30,29 @@
30#region References 30#region References
31using System; 31using System;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using OpenSim.Framework.Types;
34using OpenSim.Region.Physics.Manager; 33using OpenSim.Region.Physics.Manager;
34using OpenSim.Framework.Types;
35using Axiom.Math; 35using Axiom.Math;
36using AxiomQuaternion = Axiom.Math.Quaternion; 36using AxiomQuaternion = Axiom.Math.Quaternion;
37//Specific References for BulletXPlugin 37//Specific References for BulletXPlugin
38using MonoXnaCompactMaths; //Called as MXCM 38using MonoXnaCompactMaths;
39using XnaDevRu.BulletX; 39using XnaDevRu.BulletX;
40using XnaDevRu.BulletX.Dynamics; 40using XnaDevRu.BulletX.Dynamics;
41
41#endregion 42#endregion
42 43
43namespace OpenSim.Region.Physics.BulletXPlugin 44namespace OpenSim.Region.Physics.BulletXPlugin
44{ 45{
45 /// <summary> 46 /// <summary>
47 /// This class is only here for compilations reasons
48 /// </summary>
49 public class Mesh
50 {
51 public Mesh()
52 {
53 }
54 }
55 /// <summary>
46 /// BulletXConversions are called now BulletXMaths 56 /// BulletXConversions are called now BulletXMaths
47 /// This Class converts objects and types for BulletX and give some operations 57 /// This Class converts objects and types for BulletX and give some operations
48 /// </summary> 58 /// </summary>
@@ -222,12 +232,14 @@ namespace OpenSim.Region.Physics.BulletXPlugin
222 private const int maxXY = 256; 232 private const int maxXY = 256;
223 private const int maxZ = 4096; 233 private const int maxZ = 4096;
224 private const int maxHandles = 32766; //Why? I don't know 234 private const int maxHandles = 32766; //Why? I don't know
225 private static float gravity = 9.8f; 235 private const float gravity = 9.8f;
226 private static float heightLevel0 = 77.0f; 236 private const float heightLevel0 = 77.0f;
227 private static float heightLevel1 = 200.0f; 237 private const float heightLevel1 = 200.0f;
228 private static float lowGravityFactor = 0.2f; 238 private const float lowGravityFactor = 0.2f;
229 239 //OpenSim calls Simulate 10 times per seconds. So FPS = "Simulate Calls" * simulationSubSteps = 100 FPS
230 private float[] _heightmap; 240 private const int simulationSubSteps = 10;
241 //private float[] _heightmap;
242 private BulletXPlanet _simFlatPlanet;
231 private List<BulletXCharacter> _characters = new List<BulletXCharacter>(); 243 private List<BulletXCharacter> _characters = new List<BulletXCharacter>();
232 private List<BulletXPrim> _prims = new List<BulletXPrim>(); 244 private List<BulletXPrim> _prims = new List<BulletXPrim>();
233 245
@@ -235,6 +247,11 @@ namespace OpenSim.Region.Physics.BulletXPlugin
235 public static float HeightLevel0 { get { return heightLevel0; } } 247 public static float HeightLevel0 { get { return heightLevel0; } }
236 public static float HeightLevel1 { get { return heightLevel1; } } 248 public static float HeightLevel1 { get { return heightLevel1; } }
237 public static float LowGravityFactor { get { return lowGravityFactor; } } 249 public static float LowGravityFactor { get { return lowGravityFactor; } }
250 public static int MaxXY { get { return maxXY; } }
251 public static int MaxZ { get { return maxZ; } }
252
253 private List<RigidBody> _forgottenRigidBodies = new List<RigidBody>();
254 internal string is_ex_message = "Can't remove rigidBody!: ";
238 #endregion 255 #endregion
239 256
240 public BulletXScene() 257 public BulletXScene()
@@ -250,10 +267,9 @@ namespace OpenSim.Region.Physics.BulletXPlugin
250 ddWorld = new DiscreteDynamicsWorld(cDispatcher, opCache, sicSolver); 267 ddWorld = new DiscreteDynamicsWorld(cDispatcher, opCache, sicSolver);
251 ddWorld.Gravity = new MonoXnaCompactMaths.Vector3(0, 0, -gravity); 268 ddWorld.Gravity = new MonoXnaCompactMaths.Vector3(0, 0, -gravity);
252 } 269 }
253 270 //this._heightmap = new float[65536];
254 this._heightmap = new float[65536];
255 } 271 }
256 public override PhysicsActor AddAvatar(string avName, PhysicsVector position) 272 public override PhysicsActor AddAvatar(string avName, PhysicsVector position)
257 { 273 {
258 PhysicsVector pos = new PhysicsVector(); 274 PhysicsVector pos = new PhysicsVector();
259 pos.X = position.X; 275 pos.X = position.X;
@@ -262,7 +278,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
262 BulletXCharacter newAv = null; 278 BulletXCharacter newAv = null;
263 lock (BulletXLock) 279 lock (BulletXLock)
264 { 280 {
265 newAv = new BulletXCharacter(this, pos); 281 newAv = new BulletXCharacter(avName, this, pos);
266 _characters.Add(newAv); 282 _characters.Add(newAv);
267 } 283 }
268 return newAv; 284 return newAv;
@@ -273,48 +289,98 @@ namespace OpenSim.Region.Physics.BulletXPlugin
273 { 289 {
274 lock (BulletXLock) 290 lock (BulletXLock)
275 { 291 {
292 try
293 {
294 ddWorld.RemoveRigidBody(((BulletXCharacter)actor).RigidBody);
295 }
296 catch (Exception ex)
297 {
298 BulletXMessage(is_ex_message + ex.Message, true);
299 ((BulletXCharacter)actor).RigidBody.ActivationState = ActivationState.DisableSimulation;
300 AddForgottenRigidBody(((BulletXCharacter)actor).RigidBody);
301 }
276 _characters.Remove((BulletXCharacter)actor); 302 _characters.Remove((BulletXCharacter)actor);
277 } 303 }
304 GC.Collect();
305 }
306 }
307 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position, PhysicsVector size, AxiomQuaternion rotation)
308 {
309 PhysicsActor result;
310
311 switch (pbs.ProfileShape)
312 {
313 case ProfileShape.Square:
314 /// support simple box & hollow box now; later, more shapes
315 if (pbs.ProfileHollow == 0)
316 {
317 result = AddPrim(primName, position, size, rotation, null, null);
318 }
319 else
320 {
321 Mesh mesh = null;
322 result = AddPrim(primName, position, size, rotation, mesh, pbs);
323 }
324 break;
325
326 default:
327 result = AddPrim(primName, position, size, rotation, null, null);
328 break;
278 } 329 }
330
331 return result;
279 } 332 }
280 PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, AxiomQuaternion rotation) 333 public PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Axiom.Math.Quaternion rotation)
334 {
335 return AddPrim("", position, size, rotation, null, null);
336 }
337 public PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, AxiomQuaternion rotation, Mesh mesh, PrimitiveBaseShape pbs)
281 { 338 {
282 BulletXPrim newPrim = null; 339 BulletXPrim newPrim = null;
283 lock (BulletXLock) 340 lock (BulletXLock)
284 { 341 {
285 newPrim = new BulletXPrim(this, position, size, rotation); 342 newPrim = new BulletXPrim(name, this, position, size, rotation, mesh, pbs);
286 _prims.Add(newPrim); 343 _prims.Add(newPrim);
287 } 344 }
288 return newPrim; 345 return newPrim;
289 } 346 }
290 public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position, PhysicsVector size, AxiomQuaternion rotation)
291 {
292 return AddPrim(position, size, rotation);
293 }
294
295 public override void RemovePrim(PhysicsActor prim) 347 public override void RemovePrim(PhysicsActor prim)
296 { 348 {
297 if (prim is BulletXPrim) 349 if (prim is BulletXPrim)
298 { 350 {
299 lock (BulletXLock) 351 lock (BulletXLock)
300 { 352 {
353 try
354 {
355 ddWorld.RemoveRigidBody(((BulletXPrim)prim).RigidBody);
356 }
357 catch (Exception ex)
358 {
359 BulletXMessage(is_ex_message + ex.Message, true);
360 ((BulletXPrim)prim).RigidBody.ActivationState = ActivationState.DisableSimulation;
361 AddForgottenRigidBody(((BulletXPrim)prim).RigidBody);
362 }
301 _prims.Remove((BulletXPrim)prim); 363 _prims.Remove((BulletXPrim)prim);
302 } 364 }
365 GC.Collect();
303 } 366 }
304 } 367 }
305 public override void Simulate(float timeStep) 368 public override void Simulate(float timeStep)
306 { 369 {
307 lock (BulletXLock) 370 lock (BulletXLock)
308 { 371 {
309 BXSMove(timeStep); 372 //Try to remove garbage
310 ddWorld.StepSimulation(timeStep, 0, timeStep); 373 RemoveForgottenRigidBodies();
311 //Heightmap Validation: 374 //End of remove
312 BXSValidateHeight(); 375 MoveAllObjects(timeStep);
376 ddWorld.StepSimulation(timeStep, simulationSubSteps, timeStep);
377 //Extra Heightmap Validation: BulletX's HeightFieldTerrain somestimes doesn't work so fine.
378 ValidateHeightForAll();
313 //End heightmap validation. 379 //End heightmap validation.
314 BXSUpdateKinetics(); 380 UpdateKineticsForAll();
315 } 381 }
316 } 382 }
317 private void BXSMove(float timeStep) 383 private void MoveAllObjects(float timeStep)
318 { 384 {
319 foreach (BulletXCharacter actor in _characters) 385 foreach (BulletXCharacter actor in _characters)
320 { 386 {
@@ -324,39 +390,33 @@ namespace OpenSim.Region.Physics.BulletXPlugin
324 { 390 {
325 } 391 }
326 } 392 }
327 private void BXSValidateHeight() 393 private void ValidateHeightForAll()
328 { 394 {
329 float _height; 395 float _height;
330 foreach (BulletXCharacter actor in _characters) 396 foreach (BulletXCharacter actor in _characters)
331 { 397 {
332 if ((actor.RigidBodyHorizontalPosition.x < 0) || (actor.RigidBodyHorizontalPosition.y < 0)) 398 //_height = HeightValue(actor.RigidBodyPosition);
333 { 399 _height = _simFlatPlanet.HeightValue(actor.RigidBodyPosition);
334 _height = 0;
335 }
336 else
337 {
338 _height = this._heightmap[
339 (int)Math.Round(actor.RigidBodyHorizontalPosition.x) * 256
340 + (int)Math.Round(actor.RigidBodyHorizontalPosition.y)];
341 }
342 actor.ValidateHeight(_height); 400 actor.ValidateHeight(_height);
401 //if (_simFlatPlanet.heightIsNotValid(actor.RigidBodyPosition, out _height)) actor.ValidateHeight(_height);
343 } 402 }
344 foreach (BulletXPrim prim in _prims) 403 foreach (BulletXPrim prim in _prims)
345 { 404 {
346 if ((prim.RigidBodyHorizontalPosition.x < 0) || (prim.RigidBodyHorizontalPosition.y < 0)) 405 //_height = HeightValue(prim.RigidBodyPosition);
347 { 406 _height = _simFlatPlanet.HeightValue(prim.RigidBodyPosition);
348 _height = 0;
349 }
350 else
351 {
352 _height = this._heightmap[
353 (int)Math.Round(prim.RigidBodyHorizontalPosition.x) * 256
354 + (int)Math.Round(prim.RigidBodyHorizontalPosition.y)];
355 }
356 prim.ValidateHeight(_height); 407 prim.ValidateHeight(_height);
408 //if (_simFlatPlanet.heightIsNotValid(prim.RigidBodyPosition, out _height)) prim.ValidateHeight(_height);
357 } 409 }
410 //foreach (BulletXCharacter actor in _characters)
411 //{
412 // actor.ValidateHeight(0);
413 //}
414 //foreach (BulletXPrim prim in _prims)
415 //{
416 // prim.ValidateHeight(0);
417 //}
358 } 418 }
359 private void BXSUpdateKinetics() 419 private void UpdateKineticsForAll()
360 { 420 {
361 //UpdatePosition > UpdateKinetics. 421 //UpdatePosition > UpdateKinetics.
362 //Not only position will be updated, also velocity cause acceleration. 422 //Not only position will be updated, also velocity cause acceleration.
@@ -368,6 +428,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
368 { 428 {
369 prim.UpdateKinetics(); 429 prim.UpdateKinetics();
370 } 430 }
431 //if(this._simFlatPlanet!=null) this._simFlatPlanet.Restore();
371 } 432 }
372 public override void GetResults() 433 public override void GetResults()
373 { 434 {
@@ -382,24 +443,97 @@ namespace OpenSim.Region.Physics.BulletXPlugin
382 } 443 }
383 public override void SetTerrain(float[] heightMap) 444 public override void SetTerrain(float[] heightMap)
384 { 445 {
385 //As the same as ODE, heightmap (x,y) must be swapped for BulletX 446 ////As the same as ODE, heightmap (x,y) must be swapped for BulletX
386 for (int i = 0; i < 65536; i++) 447 //for (int i = 0; i < 65536; i++)
448 //{
449 // // this._heightmap[i] = (double)heightMap[i];
450 // // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
451 // int x = i & 0xff;
452 // int y = i >> 8;
453 // this._heightmap[i] = heightMap[x * 256 + y];
454 //}
455
456 //float[] swappedHeightMap = new float[65536];
457 ////As the same as ODE, heightmap (x,y) must be swapped for BulletX
458 //for (int i = 0; i < 65536; i++)
459 //{
460 // // this._heightmap[i] = (double)heightMap[i];
461 // // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
462 // int x = i & 0xff;
463 // int y = i >> 8;
464 // swappedHeightMap[i] = heightMap[x * 256 + y];
465 //}
466 DeleteTerrain();
467 //There is a BulletXLock inside the constructor of BulletXPlanet
468 //this._simFlatPlanet = new BulletXPlanet(this, swappedHeightMap);
469 this._simFlatPlanet = new BulletXPlanet(this, heightMap);
470 //this._heightmap = heightMap;
471 }
472 public override void DeleteTerrain()
473 {
474 if (this._simFlatPlanet != null)
387 { 475 {
388 // this._heightmap[i] = (double)heightMap[i]; 476 lock (BulletXLock)
389 // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...) 477 {
390 int x = i & 0xff; 478 try
391 int y = i >> 8; 479 {
392 this._heightmap[i] = heightMap[x * 256 + y]; 480 ddWorld.RemoveRigidBody(this._simFlatPlanet.RigidBody);
481 }
482 catch (Exception ex)
483 {
484 BulletXMessage(is_ex_message + ex.Message, true);
485 this._simFlatPlanet.RigidBody.ActivationState = ActivationState.DisableSimulation;
486 AddForgottenRigidBody(this._simFlatPlanet.RigidBody);
487 }
488 }
489 this._simFlatPlanet = null;
490 GC.Collect();
491 BulletXMessage("Terrain erased!", false);
393 } 492 }
394 lock (BulletXLock) 493 //this._heightmap = null;
494 }
495 internal void AddForgottenRigidBody(RigidBody forgottenRigidBody)
496 {
497 _forgottenRigidBodies.Add(forgottenRigidBody);
498 }
499 private void RemoveForgottenRigidBodies()
500 {
501 RigidBody forgottenRigidBody;
502 int nRigidBodies = _forgottenRigidBodies.Count;
503 for(int i = nRigidBodies - 1; i >= 0; i--)
395 { 504 {
396 //Updating BulletX HeightMap??? 505 forgottenRigidBody = _forgottenRigidBodies[i];
506 try
507 {
508 ddWorld.RemoveRigidBody(forgottenRigidBody);
509 _forgottenRigidBodies.Remove(forgottenRigidBody);
510 BulletXMessage("Forgotten Rigid Body Removed", false);
511 }
512 catch (Exception ex)
513 {
514 BulletXMessage("Can't remove forgottenRigidBody!: " + ex.Message, false);
515 }
397 } 516 }
517 GC.Collect();
398 } 518 }
399 public override void DeleteTerrain() 519 internal void BulletXMessage(string message, bool isWarning)
400 { 520 {
401 521 PhysicsPluginManager.PhysicsPluginMessage("[Modified BulletX]:\t" + message, isWarning);
402 } 522 }
523 //temp
524 //private float HeightValue(MonoXnaCompactMaths.Vector3 position)
525 //{
526 // int li_x, li_y;
527 // float height;
528 // li_x = (int)Math.Round(position.X); if (li_x < 0) li_x = 0;
529 // li_y = (int)Math.Round(position.Y); if (li_y < 0) li_y = 0;
530
531 // height = this._heightmap[li_y * 256 + li_x];
532 // if (height < 0) height = 0;
533 // else if (height > maxZ) height = maxZ;
534
535 // return height;
536 //}
403 } 537 }
404 /// <summary> 538 /// <summary>
405 /// PhysicsActor Character Class for BulletX 539 /// PhysicsActor Character Class for BulletX
@@ -414,19 +548,20 @@ namespace OpenSim.Region.Physics.BulletXPlugin
414 private bool flying; 548 private bool flying;
415 private RigidBody rigidBody; 549 private RigidBody rigidBody;
416 550
417 public Axiom.Math.Vector2 RigidBodyHorizontalPosition 551 public MonoXnaCompactMaths.Vector3 RigidBodyPosition
418 { 552 {
419 get 553 get { return this.rigidBody.CenterOfMassPosition; }
420 {
421 return new Axiom.Math.Vector2(this.rigidBody.CenterOfMassPosition.X, this.rigidBody.CenterOfMassPosition.Y);
422 }
423 } 554 }
424 public BulletXCharacter(BulletXScene parent_scene, PhysicsVector pos) 555 public BulletXCharacter(BulletXScene parent_scene, PhysicsVector pos)
425 : this(parent_scene, pos, new PhysicsVector(), new PhysicsVector(), new PhysicsVector(), 556 : this("", parent_scene, pos)
557 {
558 }
559 public BulletXCharacter(String avName, BulletXScene parent_scene, PhysicsVector pos)
560 : this(avName, parent_scene, pos, new PhysicsVector(), new PhysicsVector(), new PhysicsVector(),
426 AxiomQuaternion.Identity) 561 AxiomQuaternion.Identity)
427 { 562 {
428 } 563 }
429 public BulletXCharacter(BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity, 564 public BulletXCharacter(String avName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity,
430 PhysicsVector size, PhysicsVector acceleration, AxiomQuaternion orientation) 565 PhysicsVector size, PhysicsVector acceleration, AxiomQuaternion orientation)
431 { 566 {
432 //This fields will be removed. They're temporal 567 //This fields will be removed. They're temporal
@@ -462,7 +597,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
462 MonoXnaCompactMaths.Vector3 _localInertia = new MonoXnaCompactMaths.Vector3(); 597 MonoXnaCompactMaths.Vector3 _localInertia = new MonoXnaCompactMaths.Vector3();
463 _collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0 598 _collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0
464 rigidBody = new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping, _friction, _restitution); 599 rigidBody = new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping, _friction, _restitution);
465 rigidBody.ActivationState = ActivationState.DisableDeactivation; 600 //rigidBody.ActivationState = ActivationState.DisableDeactivation;
466 //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition 601 //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
467 MonoXnaCompactMaths.Vector3 _vDebugTranslation; 602 MonoXnaCompactMaths.Vector3 _vDebugTranslation;
468 _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition; 603 _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition;
@@ -535,6 +670,13 @@ namespace OpenSim.Region.Physics.BulletXPlugin
535 } 670 }
536 } 671 }
537 } 672 }
673 public RigidBody RigidBody
674 {
675 get
676 {
677 return rigidBody;
678 }
679 }
538 public override bool Flying 680 public override bool Flying
539 { 681 {
540 get 682 get
@@ -579,8 +721,8 @@ namespace OpenSim.Region.Physics.BulletXPlugin
579 //_velocity == rigidBody.LinearVelocity 721 //_velocity == rigidBody.LinearVelocity
580 vec.X = this._velocity.X; 722 vec.X = this._velocity.X;
581 vec.Y = this._velocity.Y; 723 vec.Y = this._velocity.Y;
582 vec.Z = this._velocity.Z; 724 vec.Z = this._velocity.Z;
583 725 if ((vec.X != 0.0f) || (vec.Y != 0.0f) || (vec.Z != 0.0f)) rigidBody.Activate();
584 if (flying) 726 if (flying)
585 { 727 {
586 //Antigravity with movement 728 //Antigravity with movement
@@ -677,33 +819,37 @@ namespace OpenSim.Region.Physics.BulletXPlugin
677 //For now all prims have the same density, all prims are made of water. Be water my friend! :D 819 //For now all prims have the same density, all prims are made of water. Be water my friend! :D
678 private const float _density = 1000.0f; 820 private const float _density = 1000.0f;
679 private RigidBody rigidBody; 821 private RigidBody rigidBody;
822 private BulletXScene _parent_scene;
680 //_physical value will be linked with the prim object value 823 //_physical value will be linked with the prim object value
681 private Boolean _physical = false; 824 private Boolean _physical = false;
682 825
683 public Axiom.Math.Vector2 RigidBodyHorizontalPosition 826 public MonoXnaCompactMaths.Vector3 RigidBodyPosition
684 { 827 {
685 get 828 get { return this.rigidBody.CenterOfMassPosition; }
686 {
687 return new Axiom.Math.Vector2(this.rigidBody.CenterOfMassPosition.X, this.rigidBody.CenterOfMassPosition.Y);
688 }
689 } 829 }
690 public BulletXPrim(BulletXScene parent_scene, PhysicsVector pos, PhysicsVector size, AxiomQuaternion rotation) 830 public BulletXPrim(BulletXScene parent_scene, PhysicsVector pos, PhysicsVector size, AxiomQuaternion rotation)
691 : this(parent_scene, pos, new PhysicsVector(), size, new PhysicsVector(), rotation) 831 : this("", parent_scene, pos, new PhysicsVector(), size, new PhysicsVector(), rotation, null, null)
692 { 832 {
693 } 833 }
694 public BulletXPrim(BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity, PhysicsVector size, 834 public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector size,
695 PhysicsVector aceleration, AxiomQuaternion rotation) 835 AxiomQuaternion rotation, Mesh mesh, PrimitiveBaseShape pbs)
836 : this(primName, parent_scene, pos, new PhysicsVector(), size, new PhysicsVector(), rotation, mesh, pbs)
837 {
838 }
839 public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity, PhysicsVector size,
840 PhysicsVector aceleration, AxiomQuaternion rotation, Mesh mesh, PrimitiveBaseShape pbs)
696 { 841 {
697 _position = pos;
698 _velocity = velocity;
699 _size = size;
700 if ((size.X == 0) || (size.Y == 0) || (size.Z == 0)) throw new Exception("Size 0"); 842 if ((size.X == 0) || (size.Y == 0) || (size.Z == 0)) throw new Exception("Size 0");
843 if (rotation.Norm == 0f) rotation = AxiomQuaternion.Identity;
701 844
845 _position = pos;
846 if (_physical) _velocity = velocity; else _velocity = new PhysicsVector();
847 _size = size;
702 _acceleration = aceleration; 848 _acceleration = aceleration;
703 //Because a bug, orientation will be fixed to AxiomQuaternion.Identity 849 _orientation = rotation;
704 _orientation = AxiomQuaternion.Identity; 850
705 //_orientation = rotation; 851 _parent_scene = parent_scene;
706 //--- 852
707 //For RigidBody Constructor. The next values might change 853 //For RigidBody Constructor. The next values might change
708 float _linearDamping = 0.0f; 854 float _linearDamping = 0.0f;
709 float _angularDamping = 0.0f; 855 float _angularDamping = 0.0f;
@@ -718,9 +864,9 @@ namespace OpenSim.Region.Physics.BulletXPlugin
718 CollisionShape _collisionShape = new XnaDevRu.BulletX.BoxShape(BulletXMaths.PhysicsVectorToXnaVector3(_size) / 2.0f); 864 CollisionShape _collisionShape = new XnaDevRu.BulletX.BoxShape(BulletXMaths.PhysicsVectorToXnaVector3(_size) / 2.0f);
719 DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset); 865 DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
720 MonoXnaCompactMaths.Vector3 _localInertia = new MonoXnaCompactMaths.Vector3(); 866 MonoXnaCompactMaths.Vector3 _localInertia = new MonoXnaCompactMaths.Vector3();
721 _collisionShape.CalculateLocalInertia(Mass, out _localInertia); //Always when mass > 0 867 if(_physical) _collisionShape.CalculateLocalInertia(Mass, out _localInertia); //Always when mass > 0
722 rigidBody = new RigidBody(Mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping, _friction, _restitution); 868 rigidBody = new RigidBody(Mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping, _friction, _restitution);
723 rigidBody.ActivationState = ActivationState.DisableDeactivation; 869 //rigidBody.ActivationState = ActivationState.DisableDeactivation;
724 //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition 870 //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
725 MonoXnaCompactMaths.Vector3 _vDebugTranslation; 871 MonoXnaCompactMaths.Vector3 _vDebugTranslation;
726 _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition; 872 _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition;
@@ -754,8 +900,16 @@ namespace OpenSim.Region.Physics.BulletXPlugin
754 { 900 {
755 lock (BulletXScene.BulletXLock) 901 lock (BulletXScene.BulletXLock)
756 { 902 {
757 _velocity = value; 903 //Static objects don' have linear velocity
758 Speed(); 904 if (_physical)
905 {
906 _velocity = value;
907 Speed();
908 }
909 else
910 {
911 _velocity = new PhysicsVector();
912 }
759 } 913 }
760 } 914 }
761 } 915 }
@@ -801,7 +955,14 @@ namespace OpenSim.Region.Physics.BulletXPlugin
801 get 955 get
802 { 956 {
803 //For now all prims are boxes 957 //For now all prims are boxes
804 return _density * _size.X * _size.Y * _size.Z; 958 return (_physical ? 1 : 0) * _density * _size.X * _size.Y * _size.Z;
959 }
960 }
961 public RigidBody RigidBody
962 {
963 get
964 {
965 return rigidBody;
805 } 966 }
806 } 967 }
807 public override bool Flying 968 public override bool Flying
@@ -863,7 +1024,9 @@ namespace OpenSim.Region.Physics.BulletXPlugin
863 m.Translation = v3; 1024 m.Translation = v3;
864 rigidBody.WorldTransform = m; 1025 rigidBody.WorldTransform = m;
865 //When a Prim touch the ground it's vertical velocity it's reduced to ZERO 1026 //When a Prim touch the ground it's vertical velocity it's reduced to ZERO
866 Speed(new PhysicsVector(this.rigidBody.LinearVelocity.X, this.rigidBody.LinearVelocity.Y, 0.0f)); 1027 //Static objects don't have linear velocity
1028 if(_physical)
1029 Speed(new PhysicsVector(this.rigidBody.LinearVelocity.X, this.rigidBody.LinearVelocity.Y, 0.0f));
867 } 1030 }
868 } 1031 }
869 internal void UpdateKinetics() 1032 internal void UpdateKinetics()
@@ -872,18 +1035,12 @@ namespace OpenSim.Region.Physics.BulletXPlugin
872 { 1035 {
873 this._position = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition); 1036 this._position = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition);
874 this._velocity = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.LinearVelocity); 1037 this._velocity = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.LinearVelocity);
875 //Orientation is not implemented yet in MonoXnaCompactMaths 1038 this._orientation = BulletXMaths.XnaQuaternionToAxiomQuaternion(rigidBody.Orientation);
876 //this._orientation = BulletXMaths.XnaQuaternionToAxiomQuaternion(rigidBody.Orientation); < Good
877 //ReOrient();
878 //---
879 ReOrient();
880 } 1039 }
881 else //Doesn't updates properties. That's a cancel 1040 else //Doesn't updates properties. That's a cancel
882 { 1041 {
883 Translate(); 1042 Translate();
884 Speed(); 1043 //Speed(); //<- Static objects don't have linear velocity
885 //Orientation is not implemented yet in MonoXnaCompactMaths
886 //ReOrient();
887 ReOrient(); 1044 ReOrient();
888 } 1045 }
889 } 1046 }
@@ -915,10 +1072,49 @@ namespace OpenSim.Region.Physics.BulletXPlugin
915 } 1072 }
916 private void ReSize(PhysicsVector _newSize) 1073 private void ReSize(PhysicsVector _newSize)
917 { 1074 {
1075 //I wonder to know how to resize with a simple instruction in BulletX. It seems that for now there isn't
1076 //so i have to do it manually. That's recreating rigidbody
918 MonoXnaCompactMaths.Vector3 _newsize; 1077 MonoXnaCompactMaths.Vector3 _newsize;
919 _newsize = BulletXMaths.PhysicsVectorToXnaVector3(_newSize); 1078 _newsize = BulletXMaths.PhysicsVectorToXnaVector3(_newSize);
920 //For now all prims are Boxes 1079 if ((_newsize.X == 0) || (_newsize.Y == 0) || (_newsize.Z == 0)) throw new Exception("Size 0");
921 rigidBody.CollisionShape = new XnaDevRu.BulletX.BoxShape(BulletXMaths.PhysicsVectorToXnaVector3(_newSize) / 2.0f); 1080
1081 //For RigidBody Constructor. The next values might change
1082 float _linearDamping = 0.0f;
1083 float _angularDamping = 0.0f;
1084 float _friction = 0.5f;
1085 float _restitution = 0.0f;
1086 Matrix _startTransform = Matrix.Identity;
1087 Matrix _centerOfMassOffset = Matrix.Identity;
1088 RigidBody _tmpRigidBody;
1089 _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(this._position);
1090 //For now all prims are boxes
1091 CollisionShape _collisionShape = new XnaDevRu.BulletX.BoxShape(BulletXMaths.PhysicsVectorToXnaVector3(_newSize) / 2.0f);
1092 DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
1093 MonoXnaCompactMaths.Vector3 _localInertia = new MonoXnaCompactMaths.Vector3();
1094 if (_physical) _collisionShape.CalculateLocalInertia(Mass, out _localInertia); //Always when mass > 0
1095 _tmpRigidBody = new RigidBody(Mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping, _friction, _restitution);
1096 //rigidBody.ActivationState = ActivationState.DisableDeactivation;
1097 //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
1098 MonoXnaCompactMaths.Vector3 _vDebugTranslation;
1099 _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition;
1100 _tmpRigidBody.Translate(_vDebugTranslation);
1101 //---
1102 //There is a bug when trying to remove a rigidBody that is colliding with something..
1103 try
1104 {
1105 this._parent_scene.ddWorld.RemoveRigidBody(rigidBody);
1106 }
1107 catch(Exception ex)
1108 {
1109 this._parent_scene.BulletXMessage(this._parent_scene.is_ex_message + ex.Message, true);
1110 rigidBody.ActivationState = ActivationState.DisableSimulation;
1111 this._parent_scene.AddForgottenRigidBody(rigidBody);
1112 }
1113 rigidBody = _tmpRigidBody;
1114 this._parent_scene.ddWorld.AddRigidBody(rigidBody);
1115 if (_physical) Speed();//Static objects don't have linear velocity
1116 ReOrient();
1117 GC.Collect();
922 } 1118 }
923 private void ReOrient() 1119 private void ReOrient()
924 { 1120 {
@@ -935,4 +1131,74 @@ namespace OpenSim.Region.Physics.BulletXPlugin
935 #endregion 1131 #endregion
936 1132
937 } 1133 }
1134 /// <summary>
1135 /// This Class manage a HeighField as a RigidBody. This is for to be added in the BulletXScene
1136 /// </summary>
1137 internal class BulletXPlanet
1138 {
1139 private PhysicsVector _staticPosition;
1140 private PhysicsVector _staticVelocity;
1141 private AxiomQuaternion _staticOrientation;
1142 private float _mass;
1143 private BulletXScene _parentscene;
1144 internal float[] _heightField;
1145 private RigidBody _flatPlanet;
1146 internal RigidBody RigidBody { get { return _flatPlanet; } }
1147 internal BulletXPlanet(BulletXScene parent_scene, float[] heightField)
1148 {
1149 _staticPosition = new PhysicsVector(BulletXScene.MaxXY / 2, BulletXScene.MaxXY/2, 0);
1150 _staticVelocity = new PhysicsVector();
1151 _staticOrientation = AxiomQuaternion.Identity;
1152 _mass = 0; //No active
1153 _parentscene = parent_scene;
1154 _heightField = heightField;
1155
1156 float _linearDamping = 0.0f;
1157 float _angularDamping = 0.0f;
1158 float _friction = 0.5f;
1159 float _restitution = 0.0f;
1160 Matrix _startTransform = Matrix.Identity;
1161 Matrix _centerOfMassOffset = Matrix.Identity;
1162
1163 lock (BulletXScene.BulletXLock)
1164 {
1165 try
1166 {
1167 _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(_staticPosition);
1168 CollisionShape _collisionShape = new HeightfieldTerrainShape(BulletXScene.MaxXY, BulletXScene.MaxXY, _heightField, (float)BulletXScene.MaxZ, 2, true, false);
1169 DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
1170 MonoXnaCompactMaths.Vector3 _localInertia = new MonoXnaCompactMaths.Vector3();
1171 //_collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0
1172 _flatPlanet = new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping, _friction, _restitution);
1173 //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
1174 MonoXnaCompactMaths.Vector3 _vDebugTranslation;
1175 _vDebugTranslation = _startTransform.Translation - _flatPlanet.CenterOfMassPosition;
1176 _flatPlanet.Translate(_vDebugTranslation);
1177 parent_scene.ddWorld.AddRigidBody(_flatPlanet);
1178 }
1179 catch (Exception ex)
1180 {
1181 this._parentscene.BulletXMessage(ex.Message, true);
1182 }
1183 }
1184 this._parentscene.BulletXMessage("BulletXPlanet created.", false);
1185 }
1186 internal float HeightValue(MonoXnaCompactMaths.Vector3 position)
1187 {
1188 int li_x, li_y;
1189 float height;
1190 li_x = (int)Math.Round(position.X);
1191 if (li_x < 0) li_x = 0;
1192 if (li_x >= BulletXScene.MaxXY) li_x = BulletXScene.MaxXY - 1;
1193 li_y = (int)Math.Round(position.Y);
1194 if (li_y < 0) li_y = 0;
1195 if (li_y >= BulletXScene.MaxXY) li_y = BulletXScene.MaxXY - 1;
1196
1197 height = ((HeightfieldTerrainShape)this._flatPlanet.CollisionShape).getHeightFieldValue(li_x, li_y);
1198 if (height < 0) height = 0;
1199 else if (height > BulletXScene.MaxZ) height = BulletXScene.MaxZ;
1200
1201 return height;
1202 }
1203 }
938} 1204}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
index 15645b1..87b6d34 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
@@ -104,6 +104,19 @@ namespace OpenSim.Region.Physics.Manager
104 104
105 pluginAssembly = null; 105 pluginAssembly = null;
106 } 106 }
107 //---
108 public static void PhysicsPluginMessage(string message, bool isWarning)
109 {
110 if (isWarning)
111 {
112 MainLog.Instance.Warn("PHYSICS", message);
113 }
114 else
115 {
116 MainLog.Instance.Verbose("PHYSICS", message);
117 }
118 }
119 //---
107 } 120 }
108 121
109 public interface IPhysicsPlugin 122 public interface IPhysicsPlugin
diff --git a/ThirdPartyLicenses/BulletLicense.txt b/ThirdPartyLicenses/BulletLicense.txt
new file mode 100644
index 0000000..c3ec68c
--- /dev/null
+++ b/ThirdPartyLicenses/BulletLicense.txt
@@ -0,0 +1,17 @@
1/*
2Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
3
4This software is provided 'as-is', without any express or implied warranty.
5In no event will the authors be held liable for any damages arising from the use of this software.
6Permission is granted to anyone to use this software for any purpose,
7including commercial applications, and to alter it and redistribute it freely,
8subject to the following restrictions:
9
101. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
112. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
123. This notice may not be removed or altered from any source distribution.
13*/
14
15
16Free for commercial use, but please mail bullet@erwincoumans.com to report projects, and join the forum at
17www.continuousphysics.com/Bullet/phpBB2
diff --git a/bin/Modified.XnaDevRu.BulletX.dll b/bin/Modified.XnaDevRu.BulletX.dll
index 8de2a5f..496a99a 100644
--- a/bin/Modified.XnaDevRu.BulletX.dll
+++ b/bin/Modified.XnaDevRu.BulletX.dll
Binary files differ
diff --git a/bin/MonoXnaCompactMaths.dll b/bin/MonoXnaCompactMaths.dll
index a4e345a..1372653 100644
--- a/bin/MonoXnaCompactMaths.dll
+++ b/bin/MonoXnaCompactMaths.dll
Binary files differ
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX.suo b/libraries/ModifiedBulletX/ModifiedBulletX.suo
index 4f0acd9..6244108 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX.suo
+++ b/libraries/ModifiedBulletX/ModifiedBulletX.suo
Binary files differ
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionShapes/HeightfieldTerrainShape.cs b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionShapes/HeightfieldTerrainShape.cs
new file mode 100644
index 0000000..0f30f1f
--- /dev/null
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Collision/CollisionShapes/HeightfieldTerrainShape.cs
@@ -0,0 +1,360 @@
1/*
2 * WARNING!: this class is not in the original BulletX
3 * By the way it's based on the Bullet btHeightfieldTerrainShape:
4 * http://www.continuousphysics.com/Bullet/BulletFull/classbtHeightfieldTerrainShape.html
5 *****************************************************************************************
6 * 3RD PARTY LICENSE. The next it's the original 3rd party lincense of Bullet:
7 * ----------------------------------------------------------------------------
8Bullet Continuous Collision Detection and Physics Library
9Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
10
11This software is provided 'as-is', without any express or implied warranty.
12In no event will the authors be held liable for any damages arising from the use of this software.
13Permission is granted to anyone to use this software for any purpose,
14including commercial applications, and to alter it and redistribute it freely,
15subject to the following restrictions:
16
171. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
182. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
193. This notice may not be removed or altered from any source distribution.
20 * ------------------------------------------------------------------------------
21*/
22using System;
23using System.Collections.Generic;
24using System.Text;
25using MonoXnaCompactMaths;
26
27namespace XnaDevRu.BulletX
28{
29 public class HeightfieldTerrainShape : ConcaveShape
30 {
31 private Vector3 _localAabbMin;
32 private Vector3 _localAabbMax;
33 private Vector3 _localScaling = new Vector3(1f,1f,1f);
34 private int _width;
35 private int _length;
36 private float[] _heightfieldData;
37 private float _maxHeight;
38 private int _upAxis;
39 private bool _useFloatData;
40 private bool _flipQuadEdges;
41 private bool _useDiamondSubdivision = false;
42 private float _defaultCollisionMargin = 0.6f;
43
44 public HeightfieldTerrainShape(int width, int length, float[] heightfieldData, float maxHeight,
45 int upAxis, bool useFloatData, bool flipQuadEdges)
46 {
47 _width = width;
48 _length = length;
49 _heightfieldData = heightfieldData;
50 _maxHeight = maxHeight;
51 _upAxis = upAxis;
52 _useFloatData = useFloatData;
53 _flipQuadEdges = flipQuadEdges;
54 this.Margin = _defaultCollisionMargin;
55
56 float quantizationMargin = 1f;
57
58 //enlarge the AABB to avoid division by zero when initializing the quantization value
59 Vector3 clampValue = new Vector3(quantizationMargin, quantizationMargin, quantizationMargin);
60 Vector3 halfExtents = new Vector3(0, 0, 0);
61
62 switch (_upAxis)
63 {
64 case 0:
65 halfExtents.X = _maxHeight;
66 halfExtents.Y = _width;
67 halfExtents.Z = _length;
68 break;
69 case 1:
70 halfExtents.X = _width;
71 halfExtents.Y = _maxHeight;
72 halfExtents.Z = _length;
73 break;
74 case 2:
75 halfExtents.X = _width;
76 halfExtents.Y = _length;
77 halfExtents.Z = _maxHeight;
78 break;
79 default:
80 //need to get valid _upAxis
81 //btAssert(0);
82 throw new Exception("HeightfieldTerrainShape: need to get valid _upAxis");
83 }
84
85 halfExtents *= 0.5f;
86
87 _localAabbMin = -halfExtents - clampValue;
88 _localAabbMax = halfExtents + clampValue;
89 //Vector3 aabbSize = new Vector3();
90 //aabbSize = m_localAabbMax - m_localAabbMin;
91
92 }
93
94 protected Vector3 LocalAabbMin
95 { get { return _localAabbMin; } set { _localAabbMin = value; } }
96 protected Vector3 LocalAabbMax
97 { get { return _localAabbMax; } set { _localAabbMax = value; } }
98 public override string Name
99 {
100 get
101 {
102 return "HeightfieldTerrain";
103 }
104 }
105 public override Vector3 LocalScaling
106 {
107 get
108 {
109 return _localScaling;
110 }
111 set
112 {
113 _localScaling = value;
114 }
115 }
116 public override float Margin
117 {
118 get
119 {
120 return base.Margin;
121 }
122 set
123 {
124 base.Margin = value;
125 }
126 }
127 public override BroadphaseNativeTypes ShapeType
128 {
129 get { return BroadphaseNativeTypes.Terrain; }
130 }
131 public Vector3 HalfExtents
132 {
133 get
134 {
135 Vector3 halfExtents = new Vector3();
136 switch (_upAxis)
137 {
138 case 0:
139 halfExtents.X = 2f;//_maxHeight;
140 halfExtents.Y = _width;
141 halfExtents.Z = _length;
142 break;
143 case 1:
144 halfExtents.X = _width;
145 halfExtents.Y = 2f;// _maxHeight;
146 halfExtents.Z = _length;
147 break;
148 case 2:
149 halfExtents.X = _width;
150 halfExtents.Y = _length;
151 halfExtents.Z = 2f;// _maxHeight;
152 break;
153 default:
154 //need to get valid m_upAxis
155 //btAssert(0);
156 throw new Exception("HeightfieldTerrainShape: need to get valid _upAxis");
157 //break;
158 }
159 halfExtents *= 0.5f;
160 return halfExtents;
161 }
162 }
163
164 public override void ProcessAllTriangles(ITriangleCallback callback, Vector3 aabbMin, Vector3 aabbMax)
165 {
166 //(void)callback;
167 //(void)aabbMax;
168 //(void)aabbMin;
169
170 //quantize the aabbMin and aabbMax, and adjust the start/end ranges
171
172 int[] quantizedAabbMin = new int[3];
173 int[] quantizedAabbMax = new int[3];
174
175 Vector3 localAabbMin = aabbMin * new Vector3(1f/_localScaling.X,1f/_localScaling.Y,1f/_localScaling.Z );
176 Vector3 localAabbMax = aabbMax * new Vector3(1f/_localScaling.X,1f/_localScaling.Y,1f/_localScaling.Z);
177
178 quantizeWithClamp(ref quantizedAabbMin, localAabbMin);
179 quantizeWithClamp(ref quantizedAabbMax, localAabbMax);
180
181
182
183 int startX=0;
184 int endX=_width-1;
185 int startJ=0;
186 int endJ=_length-1;
187
188 switch(_upAxis)
189 {
190 case 0:
191 quantizedAabbMin[1]+=_width/2-1;
192 quantizedAabbMax[1]+=_width/2+1;
193 quantizedAabbMin[2]+=_length/2-1;
194 quantizedAabbMax[2]+=_length/2+1;
195
196 if (quantizedAabbMin[1]>startX)
197 startX = quantizedAabbMin[1];
198 if (quantizedAabbMax[1]<endX)
199 endX = quantizedAabbMax[1];
200 if (quantizedAabbMin[2]>startJ)
201 startJ = quantizedAabbMin[2];
202 if (quantizedAabbMax[2]<endJ)
203 endJ = quantizedAabbMax[2];
204 break;
205 case 1:
206 quantizedAabbMin[0]+=_width/2-1;
207 quantizedAabbMax[0]+=_width/2+1;
208 quantizedAabbMin[2]+=_length/2-1;
209 quantizedAabbMax[2]+=_length/2+1;
210
211 if (quantizedAabbMin[0]>startX)
212 startX = quantizedAabbMin[0];
213 if (quantizedAabbMax[0]<endX)
214 endX = quantizedAabbMax[0];
215 if (quantizedAabbMin[2]>startJ)
216 startJ = quantizedAabbMin[2];
217 if (quantizedAabbMax[2]<endJ)
218 endJ = quantizedAabbMax[2];
219 break;
220 case 2:
221 quantizedAabbMin[0]+=_width/2-1;
222 quantizedAabbMax[0]+=_width/2+1;
223 quantizedAabbMin[1]+=_length/2-1;
224 quantizedAabbMax[1]+=_length/2+1;
225
226 if (quantizedAabbMin[0]>startX)
227 startX = quantizedAabbMin[0];
228 if (quantizedAabbMax[0]<endX)
229 endX = quantizedAabbMax[0];
230 if (quantizedAabbMin[1]>startJ)
231 startJ = quantizedAabbMin[1];
232 if (quantizedAabbMax[1]<endJ)
233 endJ = quantizedAabbMax[1];
234 break;
235 default:
236 //need to get valid m_upAxis
237 throw new Exception("HeightfieldTerrainShape: need to get valid _upAxis");
238 //break;
239 }
240
241 for(int j=startJ; j<endJ; j++)
242 {
243 for(int x=startX; x<endX; x++)
244 {
245 Vector3[] vertices = new Vector3[3];
246 //if (m_flipQuadEdges || (m_useDiamondSubdivision && ((j + x) & 1)))
247 if (_flipQuadEdges || (_useDiamondSubdivision && (((j + x) & 1) > 0)))
248 {
249 //first triangle
250 getVertex(x,j,ref vertices[0]);
251 getVertex(x+1,j,ref vertices[1]);
252 getVertex(x+1,j+1,ref vertices[2]);
253 //callback->processTriangle(vertices,x,j);
254 callback.ProcessTriangle(vertices,x,j);
255
256 //second triangle
257 getVertex(x,j,ref vertices[0]);
258 getVertex(x+1,j+1,ref vertices[1]);
259 getVertex(x,j+1,ref vertices[2]);
260 //callback->processTriangle(vertices,x,j);
261 callback.ProcessTriangle(vertices, x, j);
262 }
263 else
264 {
265 //first triangle
266 getVertex(x,j,ref vertices[0]);
267 getVertex(x,j+1,ref vertices[1]);
268 getVertex(x+1,j,ref vertices[2]);
269 //callback->processTriangle(vertices,x,j);
270 callback.ProcessTriangle(vertices,x,j);
271
272 //second triangle
273 getVertex(x+1,j,ref vertices[0]);
274 getVertex(x,j+1,ref vertices[1]);
275 getVertex(x+1,j+1,ref vertices[2]);
276 //callback->processTriangle(vertices,x,j);
277 callback.ProcessTriangle(vertices,x,j);
278 }
279 }
280 }
281 }
282 public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
283 {
284 //aabbMin = new Vector3(-1e30f, -1e30f, -1e30f);
285 //aabbMax = new Vector3(1e30f, 1e30f, 1e30f);
286
287 Vector3 halfExtents = (_localAabbMax - _localAabbMin) * _localScaling * 0.5f;
288
289 Vector3 center = t.Translation;
290 Vector3 extent = new Vector3(Math.Abs(halfExtents.X), Math.Abs(halfExtents.Y), Math.Abs(halfExtents.Z));
291 extent += new Vector3(Margin, Margin, Margin);
292
293 aabbMin = center - extent;
294 aabbMax = center + extent;
295 }
296 public override void CalculateLocalInertia(float mass, out Vector3 inertia)
297 {
298 //moving concave objects not supported
299 inertia = new Vector3();
300 }
301 public float getHeightFieldValue(int x,int y)
302 {
303 float val = 0f;
304 if (_useFloatData)
305 {
306 val = _heightfieldData[(y * _width) + x];
307 }
308 else
309 {
310 //assume unsigned short int
311 int heightFieldValue = (int)_heightfieldData[(y * _width) + x];
312 val = heightFieldValue * _maxHeight/65535f;
313 }
314 return val;
315 }
316 public void getVertex(int x,int y,ref Vector3 vertex)
317 {
318 if (x < 0) x = 0;
319 if (y < 0) y = 0;
320 if (x >= _width) x = _width - 1;
321 if (y >= _length) y = _length - 1;
322 float height = getHeightFieldValue(x,y);
323 switch(_upAxis)
324 {
325 case 0:
326 vertex.X = height;
327 vertex.Y = (- _width/2 ) + x;
328 vertex.Z = (- _length/2 ) + y;
329 break;
330 case 1:
331 vertex.X = (- _width/2 ) + x;
332 vertex.Y = height;
333 vertex.Z = (- _length/2 ) + y;
334 break;
335 case 2:
336 vertex.X = (- _width/2 ) + x;
337 vertex.Y = (- _length/2 ) + y;
338 vertex.Z = height;
339 break;
340 default:
341 //need to get valid m_upAxis
342 throw new Exception("HeightfieldTerrainShape: need to get valid _upAxis");
343 //break;
344 }
345 vertex *= _localScaling;
346 }
347 public void quantizeWithClamp(ref int[] _out,Vector3 point)
348 {
349 Vector3 clampedPoint = point;
350 MathHelper.SetMax(ref clampedPoint,_localAabbMin);
351 MathHelper.SetMin(ref clampedPoint, _localAabbMax);
352 Vector3 v = clampedPoint;
353
354 _out[0] = (int)(v.X);
355 _out[1] = (int)(v.Y);
356 _out[2] = (int)(v.Z);
357 //correct for
358 }
359 }
360}
diff --git a/libraries/ModifiedBulletX/ModifiedBulletX/Modified.XnaDevRu.BulletX.csproj b/libraries/ModifiedBulletX/ModifiedBulletX/Modified.XnaDevRu.BulletX.csproj
index 06b98bc..3aead70 100644
--- a/libraries/ModifiedBulletX/ModifiedBulletX/Modified.XnaDevRu.BulletX.csproj
+++ b/libraries/ModifiedBulletX/ModifiedBulletX/Modified.XnaDevRu.BulletX.csproj
@@ -78,6 +78,7 @@
78 <Compile Include="Collision\CollisionShapes\CylinderShapeZ.cs" /> 78 <Compile Include="Collision\CollisionShapes\CylinderShapeZ.cs" />
79 <Compile Include="Collision\CollisionShapes\EmptyShape.cs" /> 79 <Compile Include="Collision\CollisionShapes\EmptyShape.cs" />
80 <Compile Include="Collision\CollisionShapes\FilteredCallback.cs" /> 80 <Compile Include="Collision\CollisionShapes\FilteredCallback.cs" />
81 <Compile Include="Collision\CollisionShapes\HeightfieldTerrainShape.cs" />
81 <Compile Include="Collision\CollisionShapes\InternalTriangleIndexCallback.cs" /> 82 <Compile Include="Collision\CollisionShapes\InternalTriangleIndexCallback.cs" />
82 <Compile Include="Collision\CollisionShapes\LocalSupportVertexCallback.cs" /> 83 <Compile Include="Collision\CollisionShapes\LocalSupportVertexCallback.cs" />
83 <Compile Include="Collision\CollisionShapes\MinkowskiSumShape.cs" /> 84 <Compile Include="Collision\CollisionShapes\MinkowskiSumShape.cs" />
diff --git a/libraries/ModifiedBulletX/MonoXnaCompactMaths/Matrix.cs b/libraries/ModifiedBulletX/MonoXnaCompactMaths/Matrix.cs
index 22842ca..9b88ab3 100644
--- a/libraries/ModifiedBulletX/MonoXnaCompactMaths/Matrix.cs
+++ b/libraries/ModifiedBulletX/MonoXnaCompactMaths/Matrix.cs
@@ -573,7 +573,11 @@ namespace MonoXnaCompactMaths
573 573
574 public static Matrix operator /(Matrix matrix1, float divider) 574 public static Matrix operator /(Matrix matrix1, float divider)
575 { 575 {
576 throw new NotImplementedException(); 576 return new Matrix(
577 matrix1.M11 / divider, matrix1.M12 / divider, matrix1.M13 / divider, matrix1.M14 / divider,
578 matrix1.M21 / divider, matrix1.M22 / divider, matrix1.M23 / divider, matrix1.M24 / divider,
579 matrix1.M31 / divider, matrix1.M32 / divider, matrix1.M33 / divider, matrix1.M34 / divider,
580 matrix1.M41 / divider, matrix1.M42 / divider, matrix1.M43 / divider, matrix1.M44 / divider);
577 } 581 }
578 582
579 583
@@ -658,7 +662,10 @@ namespace MonoXnaCompactMaths
658 662
659 public override string ToString() 663 public override string ToString()
660 { 664 {
661 throw new NotImplementedException(); 665 return "[(" + this.M11 + ", " + this.M12 + ", " + this.M13 + ", " + this.M14 + ")\n ("
666 + this.M21 + ", " + this.M22 + ", " + this.M23 + ", " + this.M24 + ")\n ("
667 + this.M31 + ", " + this.M32 + ", " + this.M33 + ", " + this.M34 + ")\n ("
668 + this.M41 + ", " + this.M42 + ", " + this.M43 + ", " + this.M44 + ")]";
662 } 669 }
663 670
664 671
diff --git a/libraries/ModifiedBulletX/MonoXnaCompactMaths/Quaternion.cs b/libraries/ModifiedBulletX/MonoXnaCompactMaths/Quaternion.cs
index b4f1873..b6d9d34 100644
--- a/libraries/ModifiedBulletX/MonoXnaCompactMaths/Quaternion.cs
+++ b/libraries/ModifiedBulletX/MonoXnaCompactMaths/Quaternion.cs
@@ -90,7 +90,91 @@ namespace MonoXnaCompactMaths
90 90
91 public static Quaternion CreateFromRotationMatrix(Matrix matrix) 91 public static Quaternion CreateFromRotationMatrix(Matrix matrix)
92 { 92 {
93 throw new NotImplementedException(); 93 float Omega2 = matrix.M44;
94 if (!isAprox(Omega2, 1f))
95 {
96 //"Normalize" the Rotation matrix. Norma = M44 = Omega2
97 matrix = matrix / Omega2;
98 }
99 //Deducted from: public static Matrix CreateFromQuaternion(Quaternion quaternion)
100 float lambda1pos, lambda2pos, lambda3pos, lambda1neg, lambda2neg, lambda3neg;
101 lambda1pos = (1f - matrix.M11 + matrix.M23 + matrix.M32) / 2f;
102 lambda2pos = (1f - matrix.M22 + matrix.M13 + matrix.M31) / 2f;
103 lambda3pos = (1f - matrix.M33 + matrix.M12 + matrix.M21) / 2f;
104 lambda1neg = (1f - matrix.M11 - matrix.M23 - matrix.M32) / 2f;
105 lambda2neg = (1f - matrix.M22 - matrix.M13 - matrix.M31) / 2f;
106 lambda3neg = (1f - matrix.M33 - matrix.M12 - matrix.M21) / 2f;
107
108 //lambadIS = (qJ + s*qK)^2
109 //q0 = w | q1 = x | q2 = y, q3 = z
110 //Every value of qI (I=1,2,3) has 4 possible values cause the sqrt
111 float[] x = new float[4]; float[] y = new float[4]; float[] z = new float[4];
112 float[] sig1 = {1f, 1f, -1f, -1f};
113 float[] sig2 = {1f, -1f, 1f, -1f};
114 for (int i = 0; i < 4; i++)
115 {
116 x[i] = (sig1[i] * (float)Math.Sqrt(lambda1pos) + sig2[i] * (float)Math.Sqrt(lambda1neg)) / 2f;
117 y[i] = (sig1[i] * (float)Math.Sqrt(lambda2pos) + sig2[i] * (float)Math.Sqrt(lambda2neg)) / 2f;
118 z[i] = (sig1[i] * (float)Math.Sqrt(lambda3pos) + sig2[i] * (float)Math.Sqrt(lambda3neg)) / 2f;
119 }
120
121 //Only a set of x, y, z are the corrects values. So it requires testing
122 int li_i=0, li_j=0, li_k=0;
123 bool lb_testL1P, lb_testL2P, lb_testL3P, lb_testL1N, lb_testL2N, lb_testL3N;
124 bool lb_superLambda = false;
125 while((li_i<4)&&(!lb_superLambda))
126 {
127 while ((li_j < 4) && (!lb_superLambda))
128 {
129 while ((li_k < 4) && (!lb_superLambda))
130 {
131 lb_testL1P = isAprox((float)(
132 Math.Pow((double)(y[li_j] + z[li_k]), 2.0)), lambda1pos);
133 lb_testL2P = isAprox((float)(
134 Math.Pow((double)(x[li_i] + z[li_k]), 2.0)), lambda2pos);
135 lb_testL3P = isAprox((float)(
136 Math.Pow((double)(x[li_i] + y[li_j]), 2.0)), lambda3pos);
137 lb_testL1N = isAprox((float)(
138 Math.Pow((double)(y[li_j] - z[li_k]), 2.0)), lambda1neg);
139 lb_testL2N = isAprox((float)(
140 Math.Pow((double)(x[li_i] - z[li_k]), 2.0)), lambda2neg);
141 lb_testL3N = isAprox((float)(
142 Math.Pow((double)(x[li_i] - y[li_j]), 2.0)), lambda3neg);
143
144 lb_superLambda = (lb_testL1P && lb_testL2P && lb_testL3P
145 && lb_testL1N && lb_testL2N && lb_testL3N);
146
147 if (!lb_superLambda) li_k++;
148 }
149 if (!lb_superLambda) li_j++;
150 }
151 if (!lb_superLambda) li_i++;
152 }
153
154 Quaternion q = new Quaternion();
155
156 if (lb_superLambda)
157 {
158 q.X = x[li_i]; q.Y = y[li_j]; q.Z = z[li_k];
159 q.W = (matrix.M12 - 2f * q.X * q.Y) / (2f * q.Z);
160
161 if (!isAprox(Omega2, 1f))
162 {
163 if (Omega2 < 0) throw new Exception("Quaternion.CreateFromRotationMatrix: Omega2 is negative!");
164 q = q * (float)Math.Sqrt(Omega2);//2 possibles values (+/-). For now only 1.
165 }
166 }
167 else
168 {
169 q = Quaternion.identity;
170 }
171
172 return q;
173 }
174 private static float floatError = 0.000001f;
175 private static bool isAprox(float test, float realValue)
176 {
177 return (((realValue * (1f - floatError)) <= test) && (test <= (realValue * (1f + floatError))));
94 } 178 }
95 179
96 180
@@ -317,7 +401,8 @@ namespace MonoXnaCompactMaths
317 401
318 public static Quaternion operator *(Quaternion quaternion1, float scaleFactor) 402 public static Quaternion operator *(Quaternion quaternion1, float scaleFactor)
319 { 403 {
320 throw new NotImplementedException(); 404 return new Quaternion(quaternion1.X / scaleFactor, quaternion1.Y / scaleFactor,
405 quaternion1.Z / scaleFactor, quaternion1.W / scaleFactor);
321 } 406 }
322 407
323 408
@@ -335,7 +420,7 @@ namespace MonoXnaCompactMaths
335 420
336 public override string ToString() 421 public override string ToString()
337 { 422 {
338 throw new NotImplementedException(); 423 return "(" + this.X + ", " + this.Y + ", " + this.Z + ", " + this.W + ")";
339 } 424 }
340 425
341 private static void Conjugate(ref Quaternion quaternion, out Quaternion result) 426 private static void Conjugate(ref Quaternion quaternion, out Quaternion result)