aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorteravus2013-01-24 07:11:32 -0500
committerteravus2013-01-24 07:11:32 -0500
commitba9d6b7337d7e95a9c8d3bd7f2e98c323f1a00be (patch)
treec530cf3e0384b96247a03b60af9ce1468337c24a /OpenSim
parent* This makes the non-physics llCastRay 'better'. It's not 'correctly work... (diff)
downloadopensim-SC_OLD-ba9d6b7337d7e95a9c8d3bd7f2e98c323f1a00be.zip
opensim-SC_OLD-ba9d6b7337d7e95a9c8d3bd7f2e98c323f1a00be.tar.gz
opensim-SC_OLD-ba9d6b7337d7e95a9c8d3bd7f2e98c323f1a00be.tar.bz2
opensim-SC_OLD-ba9d6b7337d7e95a9c8d3bd7f2e98c323f1a00be.tar.xz
* Repairs the Object updates, Collision updates, and Child Prim methods making the bulletXNA engine work again.
* The only thing that had an issue was when creating a new RigidBody, BulletXNA didn't know the type SimMotionState and the upcast type is unknown in the constructor. Therefore, I had to update the IMotionState with a new method 'SetBody'. All of the duplicated type information has been removed and BulletXNA is not relying on any non-standard types external to the library.
Diffstat (limited to 'OpenSim')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs446
1 files changed, 282 insertions, 164 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
index 49b1730..57c1308 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
@@ -27,6 +27,7 @@
27using System; 27using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.IO; 29using System.IO;
30using System.Runtime.InteropServices;
30using System.Text; 31using System.Text;
31 32
32using OpenSim.Framework; 33using OpenSim.Framework;
@@ -130,10 +131,12 @@ private sealed class BulletConstraintXNA : BulletConstraint
130 } 131 }
131} 132}
132 internal int m_maxCollisions; 133 internal int m_maxCollisions;
133 internal CollisionDesc[] m_collisionArray; 134 internal CollisionDesc[] UpdatedCollisions;
134 135 internal int LastCollisionDesc = 0;
135 internal int m_maxUpdatesPerFrame; 136 internal int m_maxUpdatesPerFrame;
136 internal EntityProperties[] m_updateArray; 137 internal int LastEntityProperty = 0;
138
139 internal EntityProperties[] UpdatedObjects;
137 140
138 private static int m_collisionsThisFrame; 141 private static int m_collisionsThisFrame;
139 private BSScene PhysicsScene { get; set; } 142 private BSScene PhysicsScene { get; set; }
@@ -900,7 +903,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
900 CollisionShape shape1 = (pShape as BulletShapeXNA).shape; 903 CollisionShape shape1 = (pShape as BulletShapeXNA).shape;
901 904
902 // TODO: Turn this from a reference copy to a Value Copy. 905 // TODO: Turn this from a reference copy to a Value Copy.
903 BulletShapeXNA shape2 = new BulletShapeXNA(shape1, BSPhysicsShapeType.SHAPE_UNKNOWN); 906 BulletShapeXNA shape2 = new BulletShapeXNA(shape1, BSShapeTypeFromBroadPhaseNativeType(shape1.GetShapeType()));
904 907
905 return shape2; 908 return shape2;
906 } 909 }
@@ -922,9 +925,9 @@ private sealed class BulletConstraintXNA : BulletConstraint
922 CollisionShape shape = (pShape as BulletShapeXNA).shape; 925 CollisionShape shape = (pShape as BulletShapeXNA).shape;
923 //UpdateSingleAabb(world, shape); 926 //UpdateSingleAabb(world, shape);
924 // TODO: Feed Update array into null 927 // TODO: Feed Update array into null
925 SimMotionState motionState = new SimMotionState(world, pLocalID, mat, null); 928 SimMotionState motionState = new SimMotionState(this, pLocalID, mat, null);
926 RigidBody body = new RigidBody(0,motionState,shape,IndexedVector3.Zero); 929 RigidBody body = new RigidBody(0,motionState,shape,IndexedVector3.Zero);
927 RigidBodyConstructionInfo constructionInfo = new RigidBodyConstructionInfo(0, new SimMotionState(world, pLocalID, mat, null),shape,IndexedVector3.Zero) 930 RigidBodyConstructionInfo constructionInfo = new RigidBodyConstructionInfo(0, motionState, shape, IndexedVector3.Zero)
928 { 931 {
929 m_mass = 0 932 m_mass = 0
930 }; 933 };
@@ -1039,8 +1042,8 @@ private sealed class BulletConstraintXNA : BulletConstraint
1039 ) 1042 )
1040 { 1043 {
1041 1044
1042 m_updateArray = updateArray; 1045 UpdatedObjects = updateArray;
1043 m_collisionArray = collisionArray; 1046 UpdatedCollisions = collisionArray;
1044 /* TODO */ 1047 /* TODO */
1045 ConfigurationParameters[] configparms = new ConfigurationParameters[1]; 1048 ConfigurationParameters[] configparms = new ConfigurationParameters[1];
1046 configparms[0] = parms; 1049 configparms[0] = parms;
@@ -1135,10 +1138,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
1135 SequentialImpulseConstraintSolver m_solver = new SequentialImpulseConstraintSolver(); 1138 SequentialImpulseConstraintSolver m_solver = new SequentialImpulseConstraintSolver();
1136 1139
1137 DiscreteDynamicsWorld world = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, cci); 1140 DiscreteDynamicsWorld world = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, cci);
1138 1141
1139
1140 world.UpdatedObjects = BSAPIXNA.GetBulletXNAEntityStruct(BSAPIXNA.BulletSimEntityStructToByteArray(updateArray, updateArray.Length));
1141 world.UpdatedCollisions = BSAPIXNA.GetBulletXNACollisionStruct(BSAPIXNA.BulletSimCollisionStructToByteArray(collisionArray, collisionArray.Length));
1142 world.LastCollisionDesc = 0; 1142 world.LastCollisionDesc = 0;
1143 world.LastEntityProperty = 0; 1143 world.LastEntityProperty = 0;
1144 1144
@@ -1332,7 +1332,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
1332 { 1332 {
1333 CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody; 1333 CollisionObject collisionObject = (pCollisionObject as BulletBodyXNA).rigidBody;
1334 CollisionShape shape = collisionObject.GetCollisionShape(); 1334 CollisionShape shape = collisionObject.GetCollisionShape();
1335 return new BulletShapeXNA(shape,BSPhysicsShapeType.SHAPE_UNKNOWN); 1335 return new BulletShapeXNA(shape, BSShapeTypeFromBroadPhaseNativeType(shape.GetShapeType()));
1336 } 1336 }
1337 1337
1338 //(PhysicsScene.World.ptr, nativeShapeData) 1338 //(PhysicsScene.World.ptr, nativeShapeData)
@@ -1395,10 +1395,148 @@ private sealed class BulletConstraintXNA : BulletConstraint
1395 CollisionShape ret = null; 1395 CollisionShape ret = null;
1396 ret = compoundshape.GetChildShape(pii); 1396 ret = compoundshape.GetChildShape(pii);
1397 compoundshape.RemoveChildShapeByIndex(pii); 1397 compoundshape.RemoveChildShapeByIndex(pii);
1398 return new BulletShapeXNA(ret, BSPhysicsShapeType.SHAPE_UNKNOWN); 1398 return new BulletShapeXNA(ret, BSShapeTypeFromBroadPhaseNativeType(ret.GetShapeType()));
1399 }
1400
1401 public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) {
1402 /* TODO */
1403 if (cShape == null)
1404 return null;
1405 CompoundShape compoundShape = (cShape as BulletShapeXNA).shape as CompoundShape;
1406 CollisionShape shape = compoundShape.GetChildShape(indx);
1407 BulletShape retShape = new BulletShapeXNA(shape, BSShapeTypeFromBroadPhaseNativeType(shape.GetShapeType()));
1408
1409
1410 return null;
1411 }
1412
1413 public BSPhysicsShapeType BSShapeTypeFromBroadPhaseNativeType(BroadphaseNativeTypes pin)
1414 {
1415 switch (pin)
1416 {
1417 case BroadphaseNativeTypes.BOX_SHAPE_PROXYTYPE:
1418 return BSPhysicsShapeType.SHAPE_BOX;
1419 break;
1420 case BroadphaseNativeTypes.TRIANGLE_SHAPE_PROXYTYPE:
1421 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1422 break;
1423
1424 case BroadphaseNativeTypes.TETRAHEDRAL_SHAPE_PROXYTYPE:
1425 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1426 break;
1427 case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE:
1428 return BSPhysicsShapeType.SHAPE_MESH;
1429 break;
1430 case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE:
1431 return BSPhysicsShapeType.SHAPE_HULL;
1432 break;
1433 case BroadphaseNativeTypes.CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
1434 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1435 break;
1436 case BroadphaseNativeTypes.CUSTOM_POLYHEDRAL_SHAPE_TYPE:
1437 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1438 break;
1439 //implicit convex shapes
1440 case BroadphaseNativeTypes.IMPLICIT_CONVEX_SHAPES_START_HERE:
1441 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1442 break;
1443 case BroadphaseNativeTypes.SPHERE_SHAPE_PROXYTYPE:
1444 return BSPhysicsShapeType.SHAPE_SPHERE;
1445 break;
1446 case BroadphaseNativeTypes.MULTI_SPHERE_SHAPE_PROXYTYPE:
1447 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1448 break;
1449 case BroadphaseNativeTypes.CAPSULE_SHAPE_PROXYTYPE:
1450 return BSPhysicsShapeType.SHAPE_CAPSULE;
1451 break;
1452 case BroadphaseNativeTypes.CONE_SHAPE_PROXYTYPE:
1453 return BSPhysicsShapeType.SHAPE_CONE;
1454 break;
1455 case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE:
1456 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1457 break;
1458 case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE:
1459 return BSPhysicsShapeType.SHAPE_CYLINDER;
1460 break;
1461 case BroadphaseNativeTypes.UNIFORM_SCALING_SHAPE_PROXYTYPE:
1462 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1463 break;
1464 case BroadphaseNativeTypes.MINKOWSKI_SUM_SHAPE_PROXYTYPE:
1465 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1466 break;
1467 case BroadphaseNativeTypes.MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE:
1468 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1469 break;
1470 case BroadphaseNativeTypes.BOX_2D_SHAPE_PROXYTYPE:
1471 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1472 break;
1473 case BroadphaseNativeTypes.CONVEX_2D_SHAPE_PROXYTYPE:
1474 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1475 break;
1476 case BroadphaseNativeTypes.CUSTOM_CONVEX_SHAPE_TYPE:
1477 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1478 break;
1479 //concave shape
1480 case BroadphaseNativeTypes.CONCAVE_SHAPES_START_HERE:
1481 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1482 break;
1483 //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
1484 case BroadphaseNativeTypes.TRIANGLE_MESH_SHAPE_PROXYTYPE:
1485 return BSPhysicsShapeType.SHAPE_MESH;
1486 break;
1487 case BroadphaseNativeTypes.SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE:
1488 return BSPhysicsShapeType.SHAPE_MESH;
1489 break;
1490 ///used for demo integration FAST/Swift collision library and Bullet
1491 case BroadphaseNativeTypes.FAST_CONCAVE_MESH_PROXYTYPE:
1492 return BSPhysicsShapeType.SHAPE_MESH;
1493 break;
1494 //terrain
1495 case BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE:
1496 return BSPhysicsShapeType.SHAPE_HEIGHTMAP;
1497 break;
1498 ///Used for GIMPACT Trimesh integration
1499 case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE:
1500 return BSPhysicsShapeType.SHAPE_MESH;
1501 break;
1502 ///Multimaterial mesh
1503 case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE:
1504 return BSPhysicsShapeType.SHAPE_MESH;
1505 break;
1506
1507 case BroadphaseNativeTypes.EMPTY_SHAPE_PROXYTYPE:
1508 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1509 break;
1510 case BroadphaseNativeTypes.STATIC_PLANE_PROXYTYPE:
1511 return BSPhysicsShapeType.SHAPE_GROUNDPLANE;
1512 break;
1513 case BroadphaseNativeTypes.CUSTOM_CONCAVE_SHAPE_TYPE:
1514 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1515 break;
1516 case BroadphaseNativeTypes.CONCAVE_SHAPES_END_HERE:
1517 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1518 break;
1519
1520 case BroadphaseNativeTypes.COMPOUND_SHAPE_PROXYTYPE:
1521 return BSPhysicsShapeType.SHAPE_COMPOUND;
1522 break;
1523
1524 case BroadphaseNativeTypes.SOFTBODY_SHAPE_PROXYTYPE:
1525 return BSPhysicsShapeType.SHAPE_MESH;
1526 break;
1527 case BroadphaseNativeTypes.HFFLUID_SHAPE_PROXYTYPE:
1528 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1529 break;
1530 case BroadphaseNativeTypes.HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE:
1531 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1532 break;
1533 case BroadphaseNativeTypes.INVALID_SHAPE_PROXYTYPE:
1534 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1535 break;
1536 }
1537 return BSPhysicsShapeType.SHAPE_UNKNOWN;
1399 } 1538 }
1400 1539
1401 public override BulletShape GetChildShapeFromCompoundShapeIndex(BulletShape cShape, int indx) { /* TODO */ return null; }
1402 public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) { /* TODO */ } 1540 public override void RemoveChildShapeFromCompoundShape(BulletShape cShape, BulletShape removeShape) { /* TODO */ }
1403 public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb) { /* TODO */ } 1541 public override void UpdateChildTransform(BulletShape pShape, int childIndex, Vector3 pos, Quaternion rot, bool shouldRecalculateLocalAabb) { /* TODO */ }
1404 1542
@@ -1636,11 +1774,21 @@ private sealed class BulletConstraintXNA : BulletConstraint
1636 return epic; 1774 return epic;
1637 } 1775 }
1638 1776
1639 private static int PhysicsStepint(BulletWorld pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount, 1777 private int PhysicsStepint(BulletWorld pWorld,float timeStep, int m_maxSubSteps, float m_fixedTimeStep, out int updatedEntityCount,
1640 out EntityProperties[] updatedEntities, out int collidersCount, out CollisionDesc[] colliders, int maxCollisions, int maxUpdates) 1778 out EntityProperties[] updatedEntities, out int collidersCount, out CollisionDesc[] colliders, int maxCollisions, int maxUpdates)
1641 { 1779 {
1642 int numSimSteps = 0; 1780 int numSimSteps = 0;
1781 Array.Clear(UpdatedObjects, 0, UpdatedObjects.Length);
1782 Array.Clear(UpdatedCollisions, 0, UpdatedCollisions.Length);
1783 LastEntityProperty=0;
1784
1785
1643 1786
1787
1788
1789
1790 LastCollisionDesc=0;
1791
1644 updatedEntityCount = 0; 1792 updatedEntityCount = 0;
1645 collidersCount = 0; 1793 collidersCount = 0;
1646 1794
@@ -1651,8 +1799,6 @@ private sealed class BulletConstraintXNA : BulletConstraint
1651 1799
1652 world.LastCollisionDesc = 0; 1800 world.LastCollisionDesc = 0;
1653 world.LastEntityProperty = 0; 1801 world.LastEntityProperty = 0;
1654 world.UpdatedObjects = new BulletXNA.EntityProperties[maxUpdates];
1655 world.UpdatedCollisions = new BulletXNA.CollisionDesc[maxCollisions];
1656 numSimSteps = world.StepSimulation(timeStep, m_maxSubSteps, m_fixedTimeStep); 1802 numSimSteps = world.StepSimulation(timeStep, m_maxSubSteps, m_fixedTimeStep);
1657 int updates = 0; 1803 int updates = 0;
1658 1804
@@ -1675,7 +1821,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
1675 IndexedVector3 contactPoint = manifoldPoint.GetPositionWorldOnB(); 1821 IndexedVector3 contactPoint = manifoldPoint.GetPositionWorldOnB();
1676 IndexedVector3 contactNormal = -manifoldPoint.m_normalWorldOnB; // make relative to A 1822 IndexedVector3 contactNormal = -manifoldPoint.m_normalWorldOnB; // make relative to A
1677 1823
1678 RecordCollision(world, objA, objB, contactPoint, contactNormal); 1824 RecordCollision(this, objA, objB, contactPoint, contactNormal);
1679 m_collisionsThisFrame ++; 1825 m_collisionsThisFrame ++;
1680 if (m_collisionsThisFrame >= 9999999) 1826 if (m_collisionsThisFrame >= 9999999)
1681 break; 1827 break;
@@ -1683,15 +1829,16 @@ private sealed class BulletConstraintXNA : BulletConstraint
1683 1829
1684 } 1830 }
1685 1831
1686 updatedEntityCount = world.LastEntityProperty; 1832 updatedEntityCount = LastEntityProperty;
1687 updatedEntities = GetBulletSimEntityStruct(BulletXNAEntityStructToByteArray(world.UpdatedObjects, world.LastEntityProperty)); 1833 updatedEntities = UpdatedObjects;
1834
1688 1835
1689 1836
1690 1837
1691 1838
1692 collidersCount = world.LastCollisionDesc; 1839 collidersCount = LastCollisionDesc;
1693 colliders = 1840 colliders = UpdatedCollisions;
1694 GetBulletSimCollisionStruct(BulletXNACollisionStructToByteArray(world.UpdatedCollisions, world.LastCollisionDesc));//new List<BulletXNA.CollisionDesc>(world.UpdatedCollisions); 1841
1695 1842
1696 } 1843 }
1697 else 1844 else
@@ -1699,8 +1846,8 @@ private sealed class BulletConstraintXNA : BulletConstraint
1699 //if (updatedEntities is null) 1846 //if (updatedEntities is null)
1700 //updatedEntities = new List<BulletXNA.EntityProperties>(); 1847 //updatedEntities = new List<BulletXNA.EntityProperties>();
1701 //updatedEntityCount = 0; 1848 //updatedEntityCount = 0;
1702 //if (colliders is null) 1849
1703 //colliders = new List<BulletXNA.CollisionDesc>(); 1850
1704 //collidersCount = 0; 1851 //collidersCount = 0;
1705 1852
1706 updatedEntities = new EntityProperties[0]; 1853 updatedEntities = new EntityProperties[0];
@@ -1712,7 +1859,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
1712 return numSimSteps; 1859 return numSimSteps;
1713 } 1860 }
1714 1861
1715 private static void RecordCollision(CollisionWorld world, CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm) 1862 private static void RecordCollision(BSAPIXNA world, CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm)
1716 { 1863 {
1717 1864
1718 IndexedVector3 contactNormal = norm; 1865 IndexedVector3 contactNormal = norm;
@@ -1733,12 +1880,12 @@ private sealed class BulletConstraintXNA : BulletConstraint
1733 1880
1734 ulong collisionID = ((ulong) idA << 32) | idB; 1881 ulong collisionID = ((ulong) idA << 32) | idB;
1735 1882
1736 BulletXNA.CollisionDesc cDesc = new BulletXNA.CollisionDesc() 1883 CollisionDesc cDesc = new CollisionDesc()
1737 { 1884 {
1738 aID = idA, 1885 aID = idA,
1739 bID = idB, 1886 bID = idB,
1740 point = contact, 1887 point = new Vector3(contact.X,contact.Y,contact.Z),
1741 normal = contactNormal 1888 normal = new Vector3(contactNormal.X,contactNormal.Y,contactNormal.Z)
1742 }; 1889 };
1743 if (world.LastCollisionDesc < world.UpdatedCollisions.Length) 1890 if (world.LastCollisionDesc < world.UpdatedCollisions.Length)
1744 world.UpdatedCollisions[world.LastCollisionDesc++] = (cDesc); 1891 world.UpdatedCollisions[world.LastCollisionDesc++] = (cDesc);
@@ -1800,160 +1947,131 @@ private sealed class BulletConstraintXNA : BulletConstraint
1800 } 1947 }
1801 return false; 1948 return false;
1802 } 1949 }
1803 1950}
1804 public static unsafe BulletXNA.CollisionDesc[] GetBulletXNACollisionStruct(byte[] buffer) 1951
1952
1953
1954
1955 public class SimMotionState : DefaultMotionState
1805 { 1956 {
1806 int count = buffer.Length/sizeof (BulletXNA.CollisionDesc); 1957 public RigidBody Rigidbody;
1807 BulletXNA.CollisionDesc[] result = new BulletXNA.CollisionDesc[count]; 1958 public Vector3 ZeroVect;
1808 BulletXNA.CollisionDesc* ptr; 1959
1809 fixed (byte* localBytes = new byte[buffer.Length]) 1960 private IndexedMatrix m_xform;
1961
1962 private EntityProperties m_properties;
1963 private EntityProperties m_lastProperties;
1964 private BSAPIXNA m_world;
1965
1966 const float POSITION_TOLERANCE = 0.05f;
1967 const float VELOCITY_TOLERANCE = 0.001f;
1968 const float ROTATION_TOLERANCE = 0.01f;
1969 const float ANGULARVELOCITY_TOLERANCE = 0.01f;
1970
1971 public SimMotionState(BSAPIXNA pWorld, uint id, IndexedMatrix starTransform, object frameUpdates)
1810 { 1972 {
1811 for (int i = 0; i < buffer.Length; i++) 1973 IndexedQuaternion OrientationQuaterion = starTransform.GetRotation();
1974 m_properties = new EntityProperties()
1975 {
1976 ID = id,
1977 Position = new Vector3(starTransform._origin.X, starTransform._origin.Y,starTransform._origin.Z),
1978 Rotation = new Quaternion(OrientationQuaterion.X,OrientationQuaterion.Y,OrientationQuaterion.Z,OrientationQuaterion.W)
1979 };
1980 m_lastProperties = new EntityProperties()
1812 { 1981 {
1813 localBytes[i] = buffer[i]; 1982 ID = id,
1814 } 1983 Position = new Vector3(starTransform._origin.X, starTransform._origin.Y, starTransform._origin.Z),
1815 for (int i=0;i<count;i++) 1984 Rotation = new Quaternion(OrientationQuaterion.X, OrientationQuaterion.Y, OrientationQuaterion.Z, OrientationQuaterion.W)
1816 { 1985 };
1817 ptr = (BulletXNA.CollisionDesc*) (localBytes + sizeof (BulletXNA.CollisionDesc)*i); 1986 m_world = pWorld;
1818 result[i] = new BulletXNA.CollisionDesc(); 1987 m_xform = starTransform;
1819 result[i] = *ptr;
1820 }
1821 } 1988 }
1822 return result;
1823 }
1824 1989
1825 public static unsafe CollisionDesc[] GetBulletSimCollisionStruct(byte[] buffer) 1990 public override void GetWorldTransform(out IndexedMatrix worldTrans)
1826 {
1827 int count = buffer.Length / sizeof(CollisionDesc);
1828 CollisionDesc[] result = new CollisionDesc[count];
1829 CollisionDesc* ptr;
1830 fixed (byte* localBytes = new byte[buffer.Length])
1831 { 1991 {
1832 for (int i = 0; i < buffer.Length; i++) 1992 worldTrans = m_xform;
1833 {
1834 localBytes[i] = buffer[i];
1835 }
1836 for (int i = 0; i < count; i++)
1837 {
1838 ptr = (CollisionDesc*)(localBytes + sizeof(CollisionDesc) * i);
1839 result[i] = new CollisionDesc();
1840 result[i] = *ptr;
1841 }
1842 } 1993 }
1843 return result; 1994
1844 } 1995 public override void SetWorldTransform(IndexedMatrix worldTrans)
1845 public static unsafe byte[] BulletSimCollisionStructToByteArray(CollisionDesc[] CollisionDescArray, int count)
1846 {
1847 int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length;
1848 byte[] byteArray = new byte[sizeof(CollisionDesc) * arrayLength];
1849 fixed (CollisionDesc* floatPointer = CollisionDescArray)
1850 { 1996 {
1851 fixed (byte* bytePointer = byteArray) 1997 SetWorldTransform(ref worldTrans);
1852 {
1853 CollisionDesc* read = floatPointer;
1854 CollisionDesc* write = (CollisionDesc*)bytePointer;
1855 for (int i = 0; i < arrayLength; i++)
1856 {
1857 *write++ = *read++;
1858 }
1859 }
1860 } 1998 }
1861 return byteArray; 1999
1862 } 2000 public override void SetWorldTransform(ref IndexedMatrix worldTrans)
1863 public static unsafe byte[] BulletXNACollisionStructToByteArray(BulletXNA.CollisionDesc[] CollisionDescArray, int count)
1864 {
1865 int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length;
1866 byte[] byteArray = new byte[sizeof(BulletXNA.CollisionDesc) * arrayLength];
1867 fixed (BulletXNA.CollisionDesc* floatPointer = CollisionDescArray)
1868 { 2001 {
1869 fixed (byte* bytePointer = byteArray) 2002 SetWorldTransform(ref worldTrans, false);
1870 {
1871 BulletXNA.CollisionDesc* read = floatPointer;
1872 BulletXNA.CollisionDesc* write = (BulletXNA.CollisionDesc*)bytePointer;
1873 for (int i = 0; i < arrayLength; i++)
1874 {
1875 *write++ = *read++;
1876 }
1877 }
1878 } 2003 }
1879 return byteArray; 2004 public void SetWorldTransform(ref IndexedMatrix worldTrans, bool force)
1880 }
1881 public static unsafe BulletXNA.EntityProperties[] GetBulletXNAEntityStruct(byte[] buffer)
1882 {
1883 int count = buffer.Length / sizeof(BulletXNA.EntityProperties);
1884 BulletXNA.EntityProperties[] result = new BulletXNA.EntityProperties[count];
1885 BulletXNA.EntityProperties* ptr;
1886 fixed (byte* localBytes = new byte[buffer.Length])
1887 { 2005 {
1888 for (int i = 0; i < buffer.Length; i++) 2006 m_xform = worldTrans;
1889 { 2007 // Put the new transform into m_properties
1890 localBytes[i] = buffer[i]; 2008 IndexedQuaternion OrientationQuaternion = m_xform.GetRotation();
1891 } 2009 IndexedVector3 LinearVelocityVector = Rigidbody.GetLinearVelocity();
1892 for (int i = 0; i < count; i++) 2010 IndexedVector3 AngularVelocityVector = Rigidbody.GetAngularVelocity();
2011 m_properties.Position = new Vector3(m_xform._origin.X, m_xform._origin.Y, m_xform._origin.Z);
2012 m_properties.Rotation = new Quaternion(OrientationQuaternion.X, OrientationQuaternion.Y,
2013 OrientationQuaternion.Z, OrientationQuaternion.W);
2014 // A problem with stock Bullet is that we don't get an event when an object is deactivated.
2015 // This means that the last non-zero values for linear and angular velocity
2016 // are left in the viewer who does dead reconning and the objects look like
2017 // they float off.
2018 // BulletSim ships with a patch to Bullet which creates such an event.
2019 m_properties.Velocity = new Vector3(LinearVelocityVector.X, LinearVelocityVector.Y, LinearVelocityVector.Z);
2020 m_properties.RotationalVelocity = new Vector3(AngularVelocityVector.X, AngularVelocityVector.Y, AngularVelocityVector.Z);
2021
2022 if (force
2023
2024 || !AlmostEqual(ref m_lastProperties.Position, ref m_properties.Position, POSITION_TOLERANCE)
2025 || !AlmostEqual(ref m_properties.Rotation, ref m_lastProperties.Rotation, ROTATION_TOLERANCE)
2026 // If the Velocity and AngularVelocity are zero, most likely the object has
2027 // been deactivated. If they both are zero and they have become zero recently,
2028 // make sure a property update is sent so the zeros make it to the viewer.
2029 || ((m_properties.Velocity == ZeroVect && m_properties.RotationalVelocity == ZeroVect)
2030 &&
2031 (m_properties.Velocity != m_lastProperties.Velocity ||
2032 m_properties.RotationalVelocity != m_lastProperties.RotationalVelocity))
2033 // If Velocity and AngularVelocity are non-zero but have changed, send an update.
2034 || !AlmostEqual(ref m_properties.Velocity, ref m_lastProperties.Velocity, VELOCITY_TOLERANCE)
2035 ||
2036 !AlmostEqual(ref m_properties.RotationalVelocity, ref m_lastProperties.RotationalVelocity,
2037 ANGULARVELOCITY_TOLERANCE)
2038 )
2039
2040
1893 { 2041 {
1894 ptr = (BulletXNA.EntityProperties*)(localBytes + sizeof(BulletXNA.EntityProperties) * i); 2042 // Add this update to the list of updates for this frame.
1895 result[i] = new BulletXNA.EntityProperties(); 2043 m_lastProperties = m_properties;
1896 result[i] = *ptr; 2044 if (m_world.LastEntityProperty < m_world.UpdatedObjects.Length)
2045 m_world.UpdatedObjects[m_world.LastEntityProperty++]=(m_properties);
2046
2047 //(*m_updatesThisFrame)[m_properties.ID] = &m_properties;
1897 } 2048 }
1898 } 2049
1899 return result; 2050
1900 } 2051
1901 2052
1902 public static unsafe EntityProperties[] GetBulletSimEntityStruct(byte[] buffer) 2053 }
1903 { 2054 public override void SetRigidBody(RigidBody body)
1904 int count = buffer.Length / sizeof(EntityProperties);
1905 EntityProperties[] result = new EntityProperties[count];
1906 EntityProperties* ptr;
1907 fixed (byte* localBytes = new byte[buffer.Length])
1908 { 2055 {
1909 for (int i = 0; i < buffer.Length; i++) 2056 Rigidbody = body;
1910 {
1911 localBytes[i] = buffer[i];
1912 }
1913 for (int i = 0; i < count; i++)
1914 {
1915 ptr = (EntityProperties*)(localBytes + sizeof(EntityProperties) * i);
1916 result[i] = new EntityProperties();
1917 result[i] = *ptr;
1918 }
1919 } 2057 }
1920 return result; 2058 internal static bool AlmostEqual(ref Vector3 v1, ref Vector3 v2, float nEpsilon)
1921 }
1922 public static unsafe byte[] BulletSimEntityStructToByteArray(EntityProperties[] CollisionDescArray, int count)
1923 {
1924 int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length;
1925 byte[] byteArray = new byte[sizeof(EntityProperties) * arrayLength];
1926 fixed (EntityProperties* floatPointer = CollisionDescArray)
1927 { 2059 {
1928 fixed (byte* bytePointer = byteArray) 2060 return
1929 { 2061 (((v1.X - nEpsilon) < v2.X) && (v2.X < (v1.X + nEpsilon))) &&
1930 EntityProperties* read = floatPointer; 2062 (((v1.Y - nEpsilon) < v2.Y) && (v2.Y < (v1.Y + nEpsilon))) &&
1931 EntityProperties* write = (EntityProperties*)bytePointer; 2063 (((v1.Z - nEpsilon) < v2.Z) && (v2.Z < (v1.Z + nEpsilon)));
1932 for (int i = 0; i < arrayLength; i++)
1933 {
1934 *write++ = *read++;
1935 }
1936 }
1937 } 2064 }
1938 return byteArray; 2065
1939 } 2066 internal static bool AlmostEqual(ref Quaternion v1, ref Quaternion v2, float nEpsilon)
1940 public static unsafe byte[] BulletXNAEntityStructToByteArray(BulletXNA.EntityProperties[] CollisionDescArray, int count)
1941 {
1942 int arrayLength = CollisionDescArray.Length > count ? count : CollisionDescArray.Length;
1943 byte[] byteArray = new byte[sizeof(BulletXNA.EntityProperties) * arrayLength];
1944 fixed (BulletXNA.EntityProperties* floatPointer = CollisionDescArray)
1945 { 2067 {
1946 fixed (byte* bytePointer = byteArray) 2068 return
1947 { 2069 (((v1.X - nEpsilon) < v2.X) && (v2.X < (v1.X + nEpsilon))) &&
1948 BulletXNA.EntityProperties* read = floatPointer; 2070 (((v1.Y - nEpsilon) < v2.Y) && (v2.Y < (v1.Y + nEpsilon))) &&
1949 BulletXNA.EntityProperties* write = (BulletXNA.EntityProperties*)bytePointer; 2071 (((v1.Z - nEpsilon) < v2.Z) && (v2.Z < (v1.Z + nEpsilon))) &&
1950 for (int i = 0; i < arrayLength; i++) 2072 (((v1.W - nEpsilon) < v2.W) && (v2.W < (v1.W + nEpsilon)));
1951 {
1952 *write++ = *read++;
1953 }
1954 }
1955 } 2073 }
1956 return byteArray; 2074
1957 } 2075 }
1958} 2076}
1959} 2077