aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs509
1 files changed, 343 insertions, 166 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs
index 49b1730..f63d83c 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
1786
1787
1788
1643 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,manifoldPoint.GetDistance());
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];
@@ -1711,8 +1858,64 @@ private sealed class BulletConstraintXNA : BulletConstraint
1711 } 1858 }
1712 return numSimSteps; 1859 return numSimSteps;
1713 } 1860 }
1714 1861 public void RecordGhostCollisions(PairCachingGhostObject obj)
1715 private static void RecordCollision(CollisionWorld world, CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm) 1862 {
1863 /*
1864 *void BulletSim::RecordGhostCollisions(btPairCachingGhostObject* obj)
1865{
1866 btManifoldArray manifoldArray;
1867 btBroadphasePairArray& pairArray = obj->getOverlappingPairCache()->getOverlappingPairArray();
1868 int numPairs = pairArray.size();
1869
1870 // For all the pairs of sets of contact points
1871 for (int i=0; i < numPairs; i++)
1872 {
1873 if (m_collisionsThisFrame >= m_maxCollisionsPerFrame)
1874 break;
1875
1876 manifoldArray.clear();
1877 const btBroadphasePair& pair = pairArray[i];
1878
1879 // The real representation is over in the world pair cache
1880 btBroadphasePair* collisionPair = m_worldData.dynamicsWorld->getPairCache()->findPair(pair.m_pProxy0,pair.m_pProxy1);
1881 if (!collisionPair)
1882 continue;
1883
1884 if (collisionPair->m_algorithm)
1885 collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
1886
1887 // The collision pair has sets of collision points (manifolds)
1888 for (int j=0; j < manifoldArray.size(); j++)
1889 {
1890 btPersistentManifold* contactManifold = manifoldArray[j];
1891 int numContacts = contactManifold->getNumContacts();
1892
1893 const btCollisionObject* objA = static_cast<const btCollisionObject*>(contactManifold->getBody0());
1894 const btCollisionObject* objB = static_cast<const btCollisionObject*>(contactManifold->getBody1());
1895
1896 // TODO: this is a more thurough check than the regular collision code --
1897 // here we find the penetrating contact in the manifold but for regular
1898 // collisions we assume the first point in the manifold is good enough.
1899 // Decide of this extra checking is required or if first point is good enough.
1900 for (int p=0; p < numContacts; p++)
1901 {
1902 const btManifoldPoint& pt = contactManifold->getContactPoint(p);
1903 // If a penetrating contact, this is a hit
1904 if (pt.getDistance()<0.f)
1905 {
1906 const btVector3& contactPoint = pt.getPositionWorldOnA();
1907 const btVector3& normalOnA = -pt.m_normalWorldOnB;
1908 RecordCollision(objA, objB, contactPoint, normalOnA, pt.getDistance());
1909 // Only one contact point for each set of colliding objects
1910 break;
1911 }
1912 }
1913 }
1914 }
1915}
1916 */
1917 }
1918 private static void RecordCollision(BSAPIXNA world, CollisionObject objA, CollisionObject objB, IndexedVector3 contact, IndexedVector3 norm, float penetration)
1716 { 1919 {
1717 1920
1718 IndexedVector3 contactNormal = norm; 1921 IndexedVector3 contactNormal = norm;
@@ -1733,12 +1936,14 @@ private sealed class BulletConstraintXNA : BulletConstraint
1733 1936
1734 ulong collisionID = ((ulong) idA << 32) | idB; 1937 ulong collisionID = ((ulong) idA << 32) | idB;
1735 1938
1736 BulletXNA.CollisionDesc cDesc = new BulletXNA.CollisionDesc() 1939 CollisionDesc cDesc = new CollisionDesc()
1737 { 1940 {
1738 aID = idA, 1941 aID = idA,
1739 bID = idB, 1942 bID = idB,
1740 point = contact, 1943 point = new Vector3(contact.X,contact.Y,contact.Z),
1741 normal = contactNormal 1944 normal = new Vector3(contactNormal.X,contactNormal.Y,contactNormal.Z),
1945 penetration = penetration
1946
1742 }; 1947 };
1743 if (world.LastCollisionDesc < world.UpdatedCollisions.Length) 1948 if (world.LastCollisionDesc < world.UpdatedCollisions.Length)
1744 world.UpdatedCollisions[world.LastCollisionDesc++] = (cDesc); 1949 world.UpdatedCollisions[world.LastCollisionDesc++] = (cDesc);
@@ -1764,7 +1969,8 @@ private sealed class BulletConstraintXNA : BulletConstraint
1764 return ent; 1969 return ent;
1765 } 1970 }
1766 1971
1767 public override bool UpdateParameter(BulletWorld world, uint localID, String parm, float value) { /* TODO */ return false; } 1972 public override bool UpdateParameter(BulletWorld world, uint localID, String parm, float value) { /* TODO */
1973 return false; }
1768 1974
1769 public override Vector3 GetLocalScaling(BulletShape pShape) 1975 public override Vector3 GetLocalScaling(BulletShape pShape)
1770 { 1976 {
@@ -1800,160 +2006,131 @@ private sealed class BulletConstraintXNA : BulletConstraint
1800 } 2006 }
1801 return false; 2007 return false;
1802 } 2008 }
1803 2009}
1804 public static unsafe BulletXNA.CollisionDesc[] GetBulletXNACollisionStruct(byte[] buffer) 2010
2011
2012
2013
2014 public class SimMotionState : DefaultMotionState
1805 { 2015 {
1806 int count = buffer.Length/sizeof (BulletXNA.CollisionDesc); 2016 public RigidBody Rigidbody;
1807 BulletXNA.CollisionDesc[] result = new BulletXNA.CollisionDesc[count]; 2017 public Vector3 ZeroVect;
1808 BulletXNA.CollisionDesc* ptr; 2018
1809 fixed (byte* localBytes = new byte[buffer.Length]) 2019 private IndexedMatrix m_xform;
2020
2021 private EntityProperties m_properties;
2022 private EntityProperties m_lastProperties;
2023 private BSAPIXNA m_world;
2024
2025 const float POSITION_TOLERANCE = 0.05f;
2026 const float VELOCITY_TOLERANCE = 0.001f;
2027 const float ROTATION_TOLERANCE = 0.01f;
2028 const float ANGULARVELOCITY_TOLERANCE = 0.01f;
2029
2030 public SimMotionState(BSAPIXNA pWorld, uint id, IndexedMatrix starTransform, object frameUpdates)
1810 { 2031 {
1811 for (int i = 0; i < buffer.Length; i++) 2032 IndexedQuaternion OrientationQuaterion = starTransform.GetRotation();
1812 { 2033 m_properties = new EntityProperties()
1813 localBytes[i] = buffer[i]; 2034 {
1814 } 2035 ID = id,
1815 for (int i=0;i<count;i++) 2036 Position = new Vector3(starTransform._origin.X, starTransform._origin.Y,starTransform._origin.Z),
2037 Rotation = new Quaternion(OrientationQuaterion.X,OrientationQuaterion.Y,OrientationQuaterion.Z,OrientationQuaterion.W)
2038 };
2039 m_lastProperties = new EntityProperties()
1816 { 2040 {
1817 ptr = (BulletXNA.CollisionDesc*) (localBytes + sizeof (BulletXNA.CollisionDesc)*i); 2041 ID = id,
1818 result[i] = new BulletXNA.CollisionDesc(); 2042 Position = new Vector3(starTransform._origin.X, starTransform._origin.Y, starTransform._origin.Z),
1819 result[i] = *ptr; 2043 Rotation = new Quaternion(OrientationQuaterion.X, OrientationQuaterion.Y, OrientationQuaterion.Z, OrientationQuaterion.W)
1820 } 2044 };
2045 m_world = pWorld;
2046 m_xform = starTransform;
1821 } 2047 }
1822 return result;
1823 }
1824 2048
1825 public static unsafe CollisionDesc[] GetBulletSimCollisionStruct(byte[] buffer) 2049 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 { 2050 {
1832 for (int i = 0; i < buffer.Length; i++) 2051 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 } 2052 }
1843 return result; 2053
1844 } 2054 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 { 2055 {
1851 fixed (byte* bytePointer = byteArray) 2056 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 } 2057 }
1861 return byteArray; 2058
1862 } 2059 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 { 2060 {
1869 fixed (byte* bytePointer = byteArray) 2061 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 } 2062 }
1879 return byteArray; 2063 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 { 2064 {
1888 for (int i = 0; i < buffer.Length; i++) 2065 m_xform = worldTrans;
1889 { 2066 // Put the new transform into m_properties
1890 localBytes[i] = buffer[i]; 2067 IndexedQuaternion OrientationQuaternion = m_xform.GetRotation();
1891 } 2068 IndexedVector3 LinearVelocityVector = Rigidbody.GetLinearVelocity();
1892 for (int i = 0; i < count; i++) 2069 IndexedVector3 AngularVelocityVector = Rigidbody.GetAngularVelocity();
2070 m_properties.Position = new Vector3(m_xform._origin.X, m_xform._origin.Y, m_xform._origin.Z);
2071 m_properties.Rotation = new Quaternion(OrientationQuaternion.X, OrientationQuaternion.Y,
2072 OrientationQuaternion.Z, OrientationQuaternion.W);
2073 // A problem with stock Bullet is that we don't get an event when an object is deactivated.
2074 // This means that the last non-zero values for linear and angular velocity
2075 // are left in the viewer who does dead reconning and the objects look like
2076 // they float off.
2077 // BulletSim ships with a patch to Bullet which creates such an event.
2078 m_properties.Velocity = new Vector3(LinearVelocityVector.X, LinearVelocityVector.Y, LinearVelocityVector.Z);
2079 m_properties.RotationalVelocity = new Vector3(AngularVelocityVector.X, AngularVelocityVector.Y, AngularVelocityVector.Z);
2080
2081 if (force
2082
2083 || !AlmostEqual(ref m_lastProperties.Position, ref m_properties.Position, POSITION_TOLERANCE)
2084 || !AlmostEqual(ref m_properties.Rotation, ref m_lastProperties.Rotation, ROTATION_TOLERANCE)
2085 // If the Velocity and AngularVelocity are zero, most likely the object has
2086 // been deactivated. If they both are zero and they have become zero recently,
2087 // make sure a property update is sent so the zeros make it to the viewer.
2088 || ((m_properties.Velocity == ZeroVect && m_properties.RotationalVelocity == ZeroVect)
2089 &&
2090 (m_properties.Velocity != m_lastProperties.Velocity ||
2091 m_properties.RotationalVelocity != m_lastProperties.RotationalVelocity))
2092 // If Velocity and AngularVelocity are non-zero but have changed, send an update.
2093 || !AlmostEqual(ref m_properties.Velocity, ref m_lastProperties.Velocity, VELOCITY_TOLERANCE)
2094 ||
2095 !AlmostEqual(ref m_properties.RotationalVelocity, ref m_lastProperties.RotationalVelocity,
2096 ANGULARVELOCITY_TOLERANCE)
2097 )
2098
2099
1893 { 2100 {
1894 ptr = (BulletXNA.EntityProperties*)(localBytes + sizeof(BulletXNA.EntityProperties) * i); 2101 // Add this update to the list of updates for this frame.
1895 result[i] = new BulletXNA.EntityProperties(); 2102 m_lastProperties = m_properties;
1896 result[i] = *ptr; 2103 if (m_world.LastEntityProperty < m_world.UpdatedObjects.Length)
2104 m_world.UpdatedObjects[m_world.LastEntityProperty++]=(m_properties);
2105
2106 //(*m_updatesThisFrame)[m_properties.ID] = &m_properties;
1897 } 2107 }
1898 } 2108
1899 return result; 2109
1900 } 2110
1901 2111
1902 public static unsafe EntityProperties[] GetBulletSimEntityStruct(byte[] buffer) 2112 }
1903 { 2113 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 { 2114 {
1909 for (int i = 0; i < buffer.Length; i++) 2115 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 } 2116 }
1920 return result; 2117 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 { 2118 {
1928 fixed (byte* bytePointer = byteArray) 2119 return
1929 { 2120 (((v1.X - nEpsilon) < v2.X) && (v2.X < (v1.X + nEpsilon))) &&
1930 EntityProperties* read = floatPointer; 2121 (((v1.Y - nEpsilon) < v2.Y) && (v2.Y < (v1.Y + nEpsilon))) &&
1931 EntityProperties* write = (EntityProperties*)bytePointer; 2122 (((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 } 2123 }
1938 return byteArray; 2124
1939 } 2125 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 { 2126 {
1946 fixed (byte* bytePointer = byteArray) 2127 return
1947 { 2128 (((v1.X - nEpsilon) < v2.X) && (v2.X < (v1.X + nEpsilon))) &&
1948 BulletXNA.EntityProperties* read = floatPointer; 2129 (((v1.Y - nEpsilon) < v2.Y) && (v2.Y < (v1.Y + nEpsilon))) &&
1949 BulletXNA.EntityProperties* write = (BulletXNA.EntityProperties*)bytePointer; 2130 (((v1.Z - nEpsilon) < v2.Z) && (v2.Z < (v1.Z + nEpsilon))) &&
1950 for (int i = 0; i < arrayLength; i++) 2131 (((v1.W - nEpsilon) < v2.W) && (v2.W < (v1.W + nEpsilon)));
1951 {
1952 *write++ = *read++;
1953 }
1954 }
1955 } 2132 }
1956 return byteArray; 2133
1957 } 2134 }
1958} 2135}
1959} 2136