diff options
author | teravus | 2013-01-24 07:11:32 -0500 |
---|---|---|
committer | teravus | 2013-01-24 07:11:32 -0500 |
commit | ba9d6b7337d7e95a9c8d3bd7f2e98c323f1a00be (patch) | |
tree | c530cf3e0384b96247a03b60af9ce1468337c24a /OpenSim/Region/Physics | |
parent | * This makes the non-physics llCastRay 'better'. It's not 'correctly work... (diff) | |
download | opensim-SC-ba9d6b7337d7e95a9c8d3bd7f2e98c323f1a00be.zip opensim-SC-ba9d6b7337d7e95a9c8d3bd7f2e98c323f1a00be.tar.gz opensim-SC-ba9d6b7337d7e95a9c8d3bd7f2e98c323f1a00be.tar.bz2 opensim-SC-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/Region/Physics')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 446 |
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 @@ | |||
27 | using System; | 27 | using System; |
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.IO; | 29 | using System.IO; |
30 | using System.Runtime.InteropServices; | ||
30 | using System.Text; | 31 | using System.Text; |
31 | 32 | ||
32 | using OpenSim.Framework; | 33 | using 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 | |