diff --git a/extern/bullet3/CMakeLists.txt b/extern/bullet3/CMakeLists.txt index f8c90bc..e6ac7b8 100644 --- a/extern/bullet3/CMakeLists.txt +++ b/extern/bullet3/CMakeLists.txt @@ -361,6 +361,32 @@ add_library(BulletCollision STATIC EXCLUDE_FROM_ALL Bullet3Collision/NarrowPhaseCollision/shared/b3UpdateAabbs.h) target_include_directories(BulletCollision PUBLIC $) +add_library(BulletFileLoader STATIC EXCLUDE_FROM_ALL + Serialize/BulletFileLoader/bChunk.cpp + Serialize/BulletFileLoader/bDNA.cpp + Serialize/BulletFileLoader/bFile.cpp + Serialize/BulletFileLoader/btBulletFile.cpp + Serialize/BulletFileLoader/bChunk.h + Serialize/BulletFileLoader/bCommon.h + Serialize/BulletFileLoader/bDefines.h + Serialize/BulletFileLoader/bDNA.h + Serialize/BulletFileLoader/bFile.h + Serialize/BulletFileLoader/btBulletFile.h +) +target_include_directories(BulletFileLoader PUBLIC $) +target_link_libraries(BulletFileLoader PUBLIC LinearMath) + +add_library(BulletWorldImporter STATIC EXCLUDE_FROM_ALL + Serialize/BulletWorldImporter/btMultiBodyWorldImporter.cpp + Serialize/BulletWorldImporter/btMultiBodyWorldImporter.h + Serialize/BulletWorldImporter/btBulletWorldImporter.cpp + Serialize/BulletWorldImporter/btBulletWorldImporter.h + Serialize/BulletWorldImporter/btWorldImporter.cpp + Serialize/BulletWorldImporter/btWorldImporter.h +) +target_include_directories(BulletWorldImporter PUBLIC $) +target_link_libraries(BulletWorldImporter PUBLIC BulletFileLoader BulletDynamics) + # add_library(BulletDynamics STATIC EXCLUDE_FROM_ALL BulletDynamics/Character/btCharacterControllerInterface.h diff --git a/extern/bullet3/Serialize/BulletFileLoader/autogenerated/bullet.h b/extern/bullet3/Serialize/BulletFileLoader/autogenerated/bullet.h new file mode 100644 index 0000000..bfec77b --- /dev/null +++ b/extern/bullet3/Serialize/BulletFileLoader/autogenerated/bullet.h @@ -0,0 +1,1580 @@ +/* Copyright (C) 2011 Erwin Coumans & Charlie C +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. 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. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ +// Auto generated from Bullet/Extras/HeaderGenerator/bulletGenerate.py +#ifndef __BULLET_H__ +#define __BULLET_H__ +namespace Bullet { + +// put an empty struct in the case +typedef struct bInvalidHandle { + int unused; +}bInvalidHandle; + + class PointerArray; + class btPhysicsSystem; + class ListBase; + class btVector3FloatData; + class btVector3DoubleData; + class btQuaternionFloatData; + class btQuaternionDoubleData; + class btMatrix3x3FloatData; + class btMatrix3x3DoubleData; + class btTransformFloatData; + class btTransformDoubleData; + class btBvhSubtreeInfoData; + class btOptimizedBvhNodeFloatData; + class btOptimizedBvhNodeDoubleData; + class btQuantizedBvhNodeData; + class btQuantizedBvhFloatData; + class btQuantizedBvhDoubleData; + class btCollisionShapeData; + class btStaticPlaneShapeData; + class btConvexInternalShapeData; + class btPositionAndRadius; + class btMultiSphereShapeData; + class btIntIndexData; + class btShortIntIndexData; + class btShortIntIndexTripletData; + class btCharIndexTripletData; + class btMeshPartData; + class btStridingMeshInterfaceData; + class btTriangleMeshShapeData; + class btScaledTriangleMeshShapeData; + class btCompoundShapeChildData; + class btCompoundShapeData; + class btCylinderShapeData; + class btConeShapeData; + class btCapsuleShapeData; + class btTriangleInfoData; + class btTriangleInfoMapData; + class btPersistentManifoldDoubleData; + class btPersistentManifoldFloatData; + class btGImpactMeshShapeData; + class btConvexHullShapeData; + class btCollisionObjectDoubleData; + class btCollisionObjectFloatData; + class btContactSolverInfoDoubleData; + class btContactSolverInfoFloatData; + class btDynamicsWorldDoubleData; + class btDynamicsWorldFloatData; + class btRigidBodyFloatData; + class btRigidBodyDoubleData; + class btConstraintInfo1; + class btTypedConstraintFloatData; + class btTypedConstraintData; + class btTypedConstraintDoubleData; + class btPoint2PointConstraintFloatData; + class btPoint2PointConstraintDoubleData2; + class btPoint2PointConstraintDoubleData; + class btHingeConstraintDoubleData; + class btHingeConstraintFloatData; + class btHingeConstraintDoubleData2; + class btConeTwistConstraintDoubleData; + class btConeTwistConstraintData; + class btGeneric6DofConstraintData; + class btGeneric6DofConstraintDoubleData2; + class btGeneric6DofSpringConstraintData; + class btGeneric6DofSpringConstraintDoubleData2; + class btGeneric6DofSpring2ConstraintData; + class btGeneric6DofSpring2ConstraintDoubleData2; + class btSliderConstraintData; + class btSliderConstraintDoubleData; + class btGearConstraintFloatData; + class btGearConstraintDoubleData; + class SoftBodyMaterialData; + class SoftBodyNodeData; + class SoftBodyLinkData; + class SoftBodyFaceData; + class SoftBodyTetraData; + class SoftRigidAnchorData; + class SoftBodyConfigData; + class SoftBodyPoseData; + class SoftBodyClusterData; + class btSoftBodyJointData; + class btSoftBodyFloatData; + class btMultiBodyLinkDoubleData; + class btMultiBodyLinkFloatData; + class btMultiBodyDoubleData; + class btMultiBodyFloatData; + class btMultiBodyLinkColliderFloatData; + class btMultiBodyLinkColliderDoubleData; +// -------------------------------------------------- // + class PointerArray + { + public: + int m_size; + int m_capacity; + void *m_data; + }; + + +// -------------------------------------------------- // + class btPhysicsSystem + { + public: + PointerArray m_collisionShapes; + PointerArray m_collisionObjects; + PointerArray m_constraints; + }; + + +// -------------------------------------------------- // + class ListBase + { + public: + void *first; + void *last; + }; + + +// -------------------------------------------------- // + class btVector3FloatData + { + public: + float m_floats[4]; + }; + + +// -------------------------------------------------- // + class btVector3DoubleData + { + public: + double m_floats[4]; + }; + + +// -------------------------------------------------- // + class btQuaternionFloatData + { + public: + float m_floats[4]; + }; + + +// -------------------------------------------------- // + class btQuaternionDoubleData + { + public: + double m_floats[4]; + }; + + +// -------------------------------------------------- // + class btMatrix3x3FloatData + { + public: + btVector3FloatData m_el[3]; + }; + + +// -------------------------------------------------- // + class btMatrix3x3DoubleData + { + public: + btVector3DoubleData m_el[3]; + }; + + +// -------------------------------------------------- // + class btTransformFloatData + { + public: + btMatrix3x3FloatData m_basis; + btVector3FloatData m_origin; + }; + + +// -------------------------------------------------- // + class btTransformDoubleData + { + public: + btMatrix3x3DoubleData m_basis; + btVector3DoubleData m_origin; + }; + + +// -------------------------------------------------- // + class btBvhSubtreeInfoData + { + public: + int m_rootNodeIndex; + int m_subtreeSize; + short m_quantizedAabbMin[3]; + short m_quantizedAabbMax[3]; + }; + + +// -------------------------------------------------- // + class btOptimizedBvhNodeFloatData + { + public: + btVector3FloatData m_aabbMinOrg; + btVector3FloatData m_aabbMaxOrg; + int m_escapeIndex; + int m_subPart; + int m_triangleIndex; + char m_pad[4]; + }; + + +// -------------------------------------------------- // + class btOptimizedBvhNodeDoubleData + { + public: + btVector3DoubleData m_aabbMinOrg; + btVector3DoubleData m_aabbMaxOrg; + int m_escapeIndex; + int m_subPart; + int m_triangleIndex; + char m_pad[4]; + }; + + +// -------------------------------------------------- // + class btQuantizedBvhNodeData + { + public: + short m_quantizedAabbMin[3]; + short m_quantizedAabbMax[3]; + int m_escapeIndexOrTriangleIndex; + }; + + +// -------------------------------------------------- // + class btQuantizedBvhFloatData + { + public: + btVector3FloatData m_bvhAabbMin; + btVector3FloatData m_bvhAabbMax; + btVector3FloatData m_bvhQuantization; + int m_curNodeIndex; + int m_useQuantization; + int m_numContiguousLeafNodes; + int m_numQuantizedContiguousNodes; + btOptimizedBvhNodeFloatData *m_contiguousNodesPtr; + btQuantizedBvhNodeData *m_quantizedContiguousNodesPtr; + btBvhSubtreeInfoData *m_subTreeInfoPtr; + int m_traversalMode; + int m_numSubtreeHeaders; + }; + + +// -------------------------------------------------- // + class btQuantizedBvhDoubleData + { + public: + btVector3DoubleData m_bvhAabbMin; + btVector3DoubleData m_bvhAabbMax; + btVector3DoubleData m_bvhQuantization; + int m_curNodeIndex; + int m_useQuantization; + int m_numContiguousLeafNodes; + int m_numQuantizedContiguousNodes; + btOptimizedBvhNodeDoubleData *m_contiguousNodesPtr; + btQuantizedBvhNodeData *m_quantizedContiguousNodesPtr; + int m_traversalMode; + int m_numSubtreeHeaders; + btBvhSubtreeInfoData *m_subTreeInfoPtr; + }; + + +// -------------------------------------------------- // + class btCollisionShapeData + { + public: + char *m_name; + int m_shapeType; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btStaticPlaneShapeData + { + public: + btCollisionShapeData m_collisionShapeData; + btVector3FloatData m_localScaling; + btVector3FloatData m_planeNormal; + float m_planeConstant; + char m_pad[4]; + }; + + +// -------------------------------------------------- // + class btConvexInternalShapeData + { + public: + btCollisionShapeData m_collisionShapeData; + btVector3FloatData m_localScaling; + btVector3FloatData m_implicitShapeDimensions; + float m_collisionMargin; + int m_padding; + }; + + +// -------------------------------------------------- // + class btPositionAndRadius + { + public: + btVector3FloatData m_pos; + float m_radius; + }; + + +// -------------------------------------------------- // + class btMultiSphereShapeData + { + public: + btConvexInternalShapeData m_convexInternalShapeData; + btPositionAndRadius *m_localPositionArrayPtr; + int m_localPositionArraySize; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btIntIndexData + { + public: + int m_value; + }; + + +// -------------------------------------------------- // + class btShortIntIndexData + { + public: + short m_value; + char m_pad[2]; + }; + + +// -------------------------------------------------- // + class btShortIntIndexTripletData + { + public: + short m_values[3]; + char m_pad[2]; + }; + + +// -------------------------------------------------- // + class btCharIndexTripletData + { + public: + char m_values[3]; + char m_pad; + }; + + +// -------------------------------------------------- // + class btMeshPartData + { + public: + btVector3FloatData *m_vertices3f; + btVector3DoubleData *m_vertices3d; + btIntIndexData *m_indices32; + btShortIntIndexTripletData *m_3indices16; + btCharIndexTripletData *m_3indices8; + btShortIntIndexData *m_indices16; + int m_numTriangles; + int m_numVertices; + }; + + +// -------------------------------------------------- // + class btStridingMeshInterfaceData + { + public: + btMeshPartData *m_meshPartsPtr; + btVector3FloatData m_scaling; + int m_numMeshParts; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btTriangleMeshShapeData + { + public: + btCollisionShapeData m_collisionShapeData; + btStridingMeshInterfaceData m_meshInterface; + btQuantizedBvhFloatData *m_quantizedFloatBvh; + btQuantizedBvhDoubleData *m_quantizedDoubleBvh; + btTriangleInfoMapData *m_triangleInfoMap; + float m_collisionMargin; + char m_pad3[4]; + }; + + +// -------------------------------------------------- // + class btScaledTriangleMeshShapeData + { + public: + btTriangleMeshShapeData m_trimeshShapeData; + btVector3FloatData m_localScaling; + }; + + +// -------------------------------------------------- // + class btCompoundShapeChildData + { + public: + btTransformFloatData m_transform; + btCollisionShapeData *m_childShape; + int m_childShapeType; + float m_childMargin; + }; + + +// -------------------------------------------------- // + class btCompoundShapeData + { + public: + btCollisionShapeData m_collisionShapeData; + btCompoundShapeChildData *m_childShapePtr; + int m_numChildShapes; + float m_collisionMargin; + }; + + +// -------------------------------------------------- // + class btCylinderShapeData + { + public: + btConvexInternalShapeData m_convexInternalShapeData; + int m_upAxis; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btConeShapeData + { + public: + btConvexInternalShapeData m_convexInternalShapeData; + int m_upIndex; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btCapsuleShapeData + { + public: + btConvexInternalShapeData m_convexInternalShapeData; + int m_upAxis; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btTriangleInfoData + { + public: + int m_flags; + float m_edgeV0V1Angle; + float m_edgeV1V2Angle; + float m_edgeV2V0Angle; + }; + + +// -------------------------------------------------- // + class btTriangleInfoMapData + { + public: + int *m_hashTablePtr; + int *m_nextPtr; + btTriangleInfoData *m_valueArrayPtr; + int *m_keyArrayPtr; + float m_convexEpsilon; + float m_planarEpsilon; + float m_equalVertexThreshold; + float m_edgeDistanceThreshold; + float m_zeroAreaThreshold; + int m_nextSize; + int m_hashTableSize; + int m_numValues; + int m_numKeys; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btPersistentManifoldDoubleData + { + public: + btVector3DoubleData m_pointCacheLocalPointA[4]; + btVector3DoubleData m_pointCacheLocalPointB[4]; + btVector3DoubleData m_pointCachePositionWorldOnA[4]; + btVector3DoubleData m_pointCachePositionWorldOnB[4]; + btVector3DoubleData m_pointCacheNormalWorldOnB[4]; + btVector3DoubleData m_pointCacheLateralFrictionDir1[4]; + btVector3DoubleData m_pointCacheLateralFrictionDir2[4]; + double m_pointCacheDistance[4]; + double m_pointCacheAppliedImpulse[4]; + double m_pointCachePrevRHS[4]; + double m_pointCacheCombinedFriction[4]; + double m_pointCacheCombinedRollingFriction[4]; + double m_pointCacheCombinedSpinningFriction[4]; + double m_pointCacheCombinedRestitution[4]; + int m_pointCachePartId0[4]; + int m_pointCachePartId1[4]; + int m_pointCacheIndex0[4]; + int m_pointCacheIndex1[4]; + int m_pointCacheContactPointFlags[4]; + double m_pointCacheAppliedImpulseLateral1[4]; + double m_pointCacheAppliedImpulseLateral2[4]; + double m_pointCacheContactMotion1[4]; + double m_pointCacheContactMotion2[4]; + double m_pointCacheContactCFM[4]; + double m_pointCacheCombinedContactStiffness1[4]; + double m_pointCacheContactERP[4]; + double m_pointCacheCombinedContactDamping1[4]; + double m_pointCacheFrictionCFM[4]; + int m_pointCacheLifeTime[4]; + int m_numCachedPoints; + int m_companionIdA; + int m_companionIdB; + int m_index1a; + int m_objectType; + double m_contactBreakingThreshold; + double m_contactProcessingThreshold; + int m_padding; + btCollisionObjectDoubleData *m_body0; + btCollisionObjectDoubleData *m_body1; + }; + + +// -------------------------------------------------- // + class btPersistentManifoldFloatData + { + public: + btVector3FloatData m_pointCacheLocalPointA[4]; + btVector3FloatData m_pointCacheLocalPointB[4]; + btVector3FloatData m_pointCachePositionWorldOnA[4]; + btVector3FloatData m_pointCachePositionWorldOnB[4]; + btVector3FloatData m_pointCacheNormalWorldOnB[4]; + btVector3FloatData m_pointCacheLateralFrictionDir1[4]; + btVector3FloatData m_pointCacheLateralFrictionDir2[4]; + float m_pointCacheDistance[4]; + float m_pointCacheAppliedImpulse[4]; + float m_pointCachePrevRHS[4]; + float m_pointCacheCombinedFriction[4]; + float m_pointCacheCombinedRollingFriction[4]; + float m_pointCacheCombinedSpinningFriction[4]; + float m_pointCacheCombinedRestitution[4]; + int m_pointCachePartId0[4]; + int m_pointCachePartId1[4]; + int m_pointCacheIndex0[4]; + int m_pointCacheIndex1[4]; + int m_pointCacheContactPointFlags[4]; + float m_pointCacheAppliedImpulseLateral1[4]; + float m_pointCacheAppliedImpulseLateral2[4]; + float m_pointCacheContactMotion1[4]; + float m_pointCacheContactMotion2[4]; + float m_pointCacheContactCFM[4]; + float m_pointCacheCombinedContactStiffness1[4]; + float m_pointCacheContactERP[4]; + float m_pointCacheCombinedContactDamping1[4]; + float m_pointCacheFrictionCFM[4]; + int m_pointCacheLifeTime[4]; + int m_numCachedPoints; + int m_companionIdA; + int m_companionIdB; + int m_index1a; + int m_objectType; + float m_contactBreakingThreshold; + float m_contactProcessingThreshold; + int m_padding; + btCollisionObjectFloatData *m_body0; + btCollisionObjectFloatData *m_body1; + }; + + +// -------------------------------------------------- // + class btGImpactMeshShapeData + { + public: + btCollisionShapeData m_collisionShapeData; + btStridingMeshInterfaceData m_meshInterface; + btVector3FloatData m_localScaling; + float m_collisionMargin; + int m_gimpactSubType; + }; + + +// -------------------------------------------------- // + class btConvexHullShapeData + { + public: + btConvexInternalShapeData m_convexInternalShapeData; + btVector3FloatData *m_unscaledPointsFloatPtr; + btVector3DoubleData *m_unscaledPointsDoublePtr; + int m_numUnscaledPoints; + char m_padding3[4]; + }; + + +// -------------------------------------------------- // + class btCollisionObjectDoubleData + { + public: + void *m_broadphaseHandle; + void *m_collisionShape; + btCollisionShapeData *m_rootCollisionShape; + char *m_name; + btTransformDoubleData m_worldTransform; + btTransformDoubleData m_interpolationWorldTransform; + btVector3DoubleData m_interpolationLinearVelocity; + btVector3DoubleData m_interpolationAngularVelocity; + btVector3DoubleData m_anisotropicFriction; + double m_contactProcessingThreshold; + double m_deactivationTime; + double m_friction; + double m_rollingFriction; + double m_contactDamping; + double m_contactStiffness; + double m_restitution; + double m_hitFraction; + double m_ccdSweptSphereRadius; + double m_ccdMotionThreshold; + int m_hasAnisotropicFriction; + int m_collisionFlags; + int m_islandTag1; + int m_companionId; + int m_activationState1; + int m_internalType; + int m_checkCollideWith; + int m_collisionFilterGroup; + int m_collisionFilterMask; + int m_uniqueId; + }; + + +// -------------------------------------------------- // + class btCollisionObjectFloatData + { + public: + void *m_broadphaseHandle; + void *m_collisionShape; + btCollisionShapeData *m_rootCollisionShape; + char *m_name; + btTransformFloatData m_worldTransform; + btTransformFloatData m_interpolationWorldTransform; + btVector3FloatData m_interpolationLinearVelocity; + btVector3FloatData m_interpolationAngularVelocity; + btVector3FloatData m_anisotropicFriction; + float m_contactProcessingThreshold; + float m_deactivationTime; + float m_friction; + float m_rollingFriction; + float m_contactDamping; + float m_contactStiffness; + float m_restitution; + float m_hitFraction; + float m_ccdSweptSphereRadius; + float m_ccdMotionThreshold; + int m_hasAnisotropicFriction; + int m_collisionFlags; + int m_islandTag1; + int m_companionId; + int m_activationState1; + int m_internalType; + int m_checkCollideWith; + int m_collisionFilterGroup; + int m_collisionFilterMask; + int m_uniqueId; + }; + + +// -------------------------------------------------- // + class btContactSolverInfoDoubleData + { + public: + double m_tau; + double m_damping; + double m_friction; + double m_timeStep; + double m_restitution; + double m_maxErrorReduction; + double m_sor; + double m_erp; + double m_erp2; + double m_globalCfm; + double m_splitImpulsePenetrationThreshold; + double m_splitImpulseTurnErp; + double m_linearSlop; + double m_warmstartingFactor; + double m_articulatedWarmstartingFactor; + double m_maxGyroscopicForce; + double m_singleAxisRollingFrictionThreshold; + int m_numIterations; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; + int m_splitImpulse; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btContactSolverInfoFloatData + { + public: + float m_tau; + float m_damping; + float m_friction; + float m_timeStep; + float m_restitution; + float m_maxErrorReduction; + float m_sor; + float m_erp; + float m_erp2; + float m_globalCfm; + float m_splitImpulsePenetrationThreshold; + float m_splitImpulseTurnErp; + float m_linearSlop; + float m_warmstartingFactor; + float m_articulatedWarmstartingFactor; + float m_maxGyroscopicForce; + float m_singleAxisRollingFrictionThreshold; + int m_numIterations; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; + int m_splitImpulse; + }; + + +// -------------------------------------------------- // + class btDynamicsWorldDoubleData + { + public: + btContactSolverInfoDoubleData m_solverInfo; + btVector3DoubleData m_gravity; + }; + + +// -------------------------------------------------- // + class btDynamicsWorldFloatData + { + public: + btContactSolverInfoFloatData m_solverInfo; + btVector3FloatData m_gravity; + }; + + +// -------------------------------------------------- // + class btRigidBodyFloatData + { + public: + btCollisionObjectFloatData m_collisionObjectData; + btMatrix3x3FloatData m_invInertiaTensorWorld; + btVector3FloatData m_linearVelocity; + btVector3FloatData m_angularVelocity; + btVector3FloatData m_angularFactor; + btVector3FloatData m_linearFactor; + btVector3FloatData m_gravity; + btVector3FloatData m_gravity_acceleration; + btVector3FloatData m_invInertiaLocal; + btVector3FloatData m_totalForce; + btVector3FloatData m_totalTorque; + float m_inverseMass; + float m_linearDamping; + float m_angularDamping; + float m_additionalDampingFactor; + float m_additionalLinearDampingThresholdSqr; + float m_additionalAngularDampingThresholdSqr; + float m_additionalAngularDampingFactor; + float m_linearSleepingThreshold; + float m_angularSleepingThreshold; + int m_additionalDamping; + }; + + +// -------------------------------------------------- // + class btRigidBodyDoubleData + { + public: + btCollisionObjectDoubleData m_collisionObjectData; + btMatrix3x3DoubleData m_invInertiaTensorWorld; + btVector3DoubleData m_linearVelocity; + btVector3DoubleData m_angularVelocity; + btVector3DoubleData m_angularFactor; + btVector3DoubleData m_linearFactor; + btVector3DoubleData m_gravity; + btVector3DoubleData m_gravity_acceleration; + btVector3DoubleData m_invInertiaLocal; + btVector3DoubleData m_totalForce; + btVector3DoubleData m_totalTorque; + double m_inverseMass; + double m_linearDamping; + double m_angularDamping; + double m_additionalDampingFactor; + double m_additionalLinearDampingThresholdSqr; + double m_additionalAngularDampingThresholdSqr; + double m_additionalAngularDampingFactor; + double m_linearSleepingThreshold; + double m_angularSleepingThreshold; + int m_additionalDamping; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btConstraintInfo1 + { + public: + int m_numConstraintRows; + int nub; + }; + + +// -------------------------------------------------- // + class btTypedConstraintFloatData + { + public: + btRigidBodyFloatData *m_rbA; + btRigidBodyFloatData *m_rbB; + char *m_name; + int m_objectType; + int m_userConstraintType; + int m_userConstraintId; + int m_needsFeedback; + float m_appliedImpulse; + float m_dbgDrawSize; + int m_disableCollisionsBetweenLinkedBodies; + int m_overrideNumSolverIterations; + float m_breakingImpulseThreshold; + int m_isEnabled; + }; + + +// -------------------------------------------------- // + class btTypedConstraintData + { + public: + bInvalidHandle *m_rbA; + bInvalidHandle *m_rbB; + char *m_name; + int m_objectType; + int m_userConstraintType; + int m_userConstraintId; + int m_needsFeedback; + float m_appliedImpulse; + float m_dbgDrawSize; + int m_disableCollisionsBetweenLinkedBodies; + int m_overrideNumSolverIterations; + float m_breakingImpulseThreshold; + int m_isEnabled; + }; + + +// -------------------------------------------------- // + class btTypedConstraintDoubleData + { + public: + btRigidBodyDoubleData *m_rbA; + btRigidBodyDoubleData *m_rbB; + char *m_name; + int m_objectType; + int m_userConstraintType; + int m_userConstraintId; + int m_needsFeedback; + double m_appliedImpulse; + double m_dbgDrawSize; + int m_disableCollisionsBetweenLinkedBodies; + int m_overrideNumSolverIterations; + double m_breakingImpulseThreshold; + int m_isEnabled; + char padding[4]; + }; + + +// -------------------------------------------------- // + class btPoint2PointConstraintFloatData + { + public: + btTypedConstraintData m_typeConstraintData; + btVector3FloatData m_pivotInA; + btVector3FloatData m_pivotInB; + }; + + +// -------------------------------------------------- // + class btPoint2PointConstraintDoubleData2 + { + public: + btTypedConstraintDoubleData m_typeConstraintData; + btVector3DoubleData m_pivotInA; + btVector3DoubleData m_pivotInB; + }; + + +// -------------------------------------------------- // + class btPoint2PointConstraintDoubleData + { + public: + btTypedConstraintData m_typeConstraintData; + btVector3DoubleData m_pivotInA; + btVector3DoubleData m_pivotInB; + }; + + +// -------------------------------------------------- // + class btHingeConstraintDoubleData + { + public: + btTypedConstraintData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; + btTransformDoubleData m_rbBFrame; + int m_useReferenceFrameA; + int m_angularOnly; + int m_enableAngularMotor; + float m_motorTargetVelocity; + float m_maxMotorImpulse; + float m_lowerLimit; + float m_upperLimit; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; + }; + + +// -------------------------------------------------- // + class btHingeConstraintFloatData + { + public: + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; + btTransformFloatData m_rbBFrame; + int m_useReferenceFrameA; + int m_angularOnly; + int m_enableAngularMotor; + float m_motorTargetVelocity; + float m_maxMotorImpulse; + float m_lowerLimit; + float m_upperLimit; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; + }; + + +// -------------------------------------------------- // + class btHingeConstraintDoubleData2 + { + public: + btTypedConstraintDoubleData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; + btTransformDoubleData m_rbBFrame; + int m_useReferenceFrameA; + int m_angularOnly; + int m_enableAngularMotor; + double m_motorTargetVelocity; + double m_maxMotorImpulse; + double m_lowerLimit; + double m_upperLimit; + double m_limitSoftness; + double m_biasFactor; + double m_relaxationFactor; + char m_padding1[4]; + }; + + +// -------------------------------------------------- // + class btConeTwistConstraintDoubleData + { + public: + btTypedConstraintDoubleData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; + btTransformDoubleData m_rbBFrame; + double m_swingSpan1; + double m_swingSpan2; + double m_twistSpan; + double m_limitSoftness; + double m_biasFactor; + double m_relaxationFactor; + double m_damping; + }; + + +// -------------------------------------------------- // + class btConeTwistConstraintData + { + public: + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; + btTransformFloatData m_rbBFrame; + float m_swingSpan1; + float m_swingSpan2; + float m_twistSpan; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; + float m_damping; + char m_pad[4]; + }; + + +// -------------------------------------------------- // + class btGeneric6DofConstraintData + { + public: + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; + btTransformFloatData m_rbBFrame; + btVector3FloatData m_linearUpperLimit; + btVector3FloatData m_linearLowerLimit; + btVector3FloatData m_angularUpperLimit; + btVector3FloatData m_angularLowerLimit; + int m_useLinearReferenceFrameA; + int m_useOffsetForConstraintFrame; + }; + + +// -------------------------------------------------- // + class btGeneric6DofConstraintDoubleData2 + { + public: + btTypedConstraintDoubleData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; + btTransformDoubleData m_rbBFrame; + btVector3DoubleData m_linearUpperLimit; + btVector3DoubleData m_linearLowerLimit; + btVector3DoubleData m_angularUpperLimit; + btVector3DoubleData m_angularLowerLimit; + int m_useLinearReferenceFrameA; + int m_useOffsetForConstraintFrame; + }; + + +// -------------------------------------------------- // + class btGeneric6DofSpringConstraintData + { + public: + btGeneric6DofConstraintData m_6dofData; + int m_springEnabled[6]; + float m_equilibriumPoint[6]; + float m_springStiffness[6]; + float m_springDamping[6]; + }; + + +// -------------------------------------------------- // + class btGeneric6DofSpringConstraintDoubleData2 + { + public: + btGeneric6DofConstraintDoubleData2 m_6dofData; + int m_springEnabled[6]; + double m_equilibriumPoint[6]; + double m_springStiffness[6]; + double m_springDamping[6]; + }; + + +// -------------------------------------------------- // + class btGeneric6DofSpring2ConstraintData + { + public: + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; + btTransformFloatData m_rbBFrame; + btVector3FloatData m_linearUpperLimit; + btVector3FloatData m_linearLowerLimit; + btVector3FloatData m_linearBounce; + btVector3FloatData m_linearStopERP; + btVector3FloatData m_linearStopCFM; + btVector3FloatData m_linearMotorERP; + btVector3FloatData m_linearMotorCFM; + btVector3FloatData m_linearTargetVelocity; + btVector3FloatData m_linearMaxMotorForce; + btVector3FloatData m_linearServoTarget; + btVector3FloatData m_linearSpringStiffness; + btVector3FloatData m_linearSpringDamping; + btVector3FloatData m_linearEquilibriumPoint; + char m_linearEnableMotor[4]; + char m_linearServoMotor[4]; + char m_linearEnableSpring[4]; + char m_linearSpringStiffnessLimited[4]; + char m_linearSpringDampingLimited[4]; + char m_padding1[4]; + btVector3FloatData m_angularUpperLimit; + btVector3FloatData m_angularLowerLimit; + btVector3FloatData m_angularBounce; + btVector3FloatData m_angularStopERP; + btVector3FloatData m_angularStopCFM; + btVector3FloatData m_angularMotorERP; + btVector3FloatData m_angularMotorCFM; + btVector3FloatData m_angularTargetVelocity; + btVector3FloatData m_angularMaxMotorForce; + btVector3FloatData m_angularServoTarget; + btVector3FloatData m_angularSpringStiffness; + btVector3FloatData m_angularSpringDamping; + btVector3FloatData m_angularEquilibriumPoint; + char m_angularEnableMotor[4]; + char m_angularServoMotor[4]; + char m_angularEnableSpring[4]; + char m_angularSpringStiffnessLimited[4]; + char m_angularSpringDampingLimited[4]; + int m_rotateOrder; + }; + + +// -------------------------------------------------- // + class btGeneric6DofSpring2ConstraintDoubleData2 + { + public: + btTypedConstraintDoubleData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; + btTransformDoubleData m_rbBFrame; + btVector3DoubleData m_linearUpperLimit; + btVector3DoubleData m_linearLowerLimit; + btVector3DoubleData m_linearBounce; + btVector3DoubleData m_linearStopERP; + btVector3DoubleData m_linearStopCFM; + btVector3DoubleData m_linearMotorERP; + btVector3DoubleData m_linearMotorCFM; + btVector3DoubleData m_linearTargetVelocity; + btVector3DoubleData m_linearMaxMotorForce; + btVector3DoubleData m_linearServoTarget; + btVector3DoubleData m_linearSpringStiffness; + btVector3DoubleData m_linearSpringDamping; + btVector3DoubleData m_linearEquilibriumPoint; + char m_linearEnableMotor[4]; + char m_linearServoMotor[4]; + char m_linearEnableSpring[4]; + char m_linearSpringStiffnessLimited[4]; + char m_linearSpringDampingLimited[4]; + char m_padding1[4]; + btVector3DoubleData m_angularUpperLimit; + btVector3DoubleData m_angularLowerLimit; + btVector3DoubleData m_angularBounce; + btVector3DoubleData m_angularStopERP; + btVector3DoubleData m_angularStopCFM; + btVector3DoubleData m_angularMotorERP; + btVector3DoubleData m_angularMotorCFM; + btVector3DoubleData m_angularTargetVelocity; + btVector3DoubleData m_angularMaxMotorForce; + btVector3DoubleData m_angularServoTarget; + btVector3DoubleData m_angularSpringStiffness; + btVector3DoubleData m_angularSpringDamping; + btVector3DoubleData m_angularEquilibriumPoint; + char m_angularEnableMotor[4]; + char m_angularServoMotor[4]; + char m_angularEnableSpring[4]; + char m_angularSpringStiffnessLimited[4]; + char m_angularSpringDampingLimited[4]; + int m_rotateOrder; + }; + + +// -------------------------------------------------- // + class btSliderConstraintData + { + public: + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; + btTransformFloatData m_rbBFrame; + float m_linearUpperLimit; + float m_linearLowerLimit; + float m_angularUpperLimit; + float m_angularLowerLimit; + int m_useLinearReferenceFrameA; + int m_useOffsetForConstraintFrame; + }; + + +// -------------------------------------------------- // + class btSliderConstraintDoubleData + { + public: + btTypedConstraintDoubleData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; + btTransformDoubleData m_rbBFrame; + double m_linearUpperLimit; + double m_linearLowerLimit; + double m_angularUpperLimit; + double m_angularLowerLimit; + int m_useLinearReferenceFrameA; + int m_useOffsetForConstraintFrame; + }; + + +// -------------------------------------------------- // + class btGearConstraintFloatData + { + public: + btTypedConstraintFloatData m_typeConstraintData; + btVector3FloatData m_axisInA; + btVector3FloatData m_axisInB; + float m_ratio; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btGearConstraintDoubleData + { + public: + btTypedConstraintDoubleData m_typeConstraintData; + btVector3DoubleData m_axisInA; + btVector3DoubleData m_axisInB; + double m_ratio; + }; + + +// -------------------------------------------------- // + class SoftBodyMaterialData + { + public: + float m_linearStiffness; + float m_angularStiffness; + float m_volumeStiffness; + int m_flags; + }; + + +// -------------------------------------------------- // + class SoftBodyNodeData + { + public: + SoftBodyMaterialData *m_material; + btVector3FloatData m_position; + btVector3FloatData m_previousPosition; + btVector3FloatData m_velocity; + btVector3FloatData m_accumulatedForce; + btVector3FloatData m_normal; + float m_inverseMass; + float m_area; + int m_attach; + int m_pad; + }; + + +// -------------------------------------------------- // + class SoftBodyLinkData + { + public: + SoftBodyMaterialData *m_material; + int m_nodeIndices[2]; + float m_restLength; + int m_bbending; + }; + + +// -------------------------------------------------- // + class SoftBodyFaceData + { + public: + btVector3FloatData m_normal; + SoftBodyMaterialData *m_material; + int m_nodeIndices[3]; + float m_restArea; + }; + + +// -------------------------------------------------- // + class SoftBodyTetraData + { + public: + btVector3FloatData m_c0[4]; + SoftBodyMaterialData *m_material; + int m_nodeIndices[4]; + float m_restVolume; + float m_c1; + float m_c2; + int m_pad; + }; + + +// -------------------------------------------------- // + class SoftRigidAnchorData + { + public: + btMatrix3x3FloatData m_c0; + btVector3FloatData m_c1; + btVector3FloatData m_localFrame; + bInvalidHandle *m_rigidBody; + int m_nodeIndex; + float m_c2; + }; + + +// -------------------------------------------------- // + class SoftBodyConfigData + { + public: + int m_aeroModel; + float m_baumgarte; + float m_damping; + float m_drag; + float m_lift; + float m_pressure; + float m_volume; + float m_dynamicFriction; + float m_poseMatch; + float m_rigidContactHardness; + float m_kineticContactHardness; + float m_softContactHardness; + float m_anchorHardness; + float m_softRigidClusterHardness; + float m_softKineticClusterHardness; + float m_softSoftClusterHardness; + float m_softRigidClusterImpulseSplit; + float m_softKineticClusterImpulseSplit; + float m_softSoftClusterImpulseSplit; + float m_maxVolume; + float m_timeScale; + int m_velocityIterations; + int m_positionIterations; + int m_driftIterations; + int m_clusterIterations; + int m_collisionFlags; + }; + + +// -------------------------------------------------- // + class SoftBodyPoseData + { + public: + btMatrix3x3FloatData m_rot; + btMatrix3x3FloatData m_scale; + btMatrix3x3FloatData m_aqq; + btVector3FloatData m_com; + btVector3FloatData *m_positions; + float *m_weights; + int m_numPositions; + int m_numWeigts; + int m_bvolume; + int m_bframe; + float m_restVolume; + int m_pad; + }; + + +// -------------------------------------------------- // + class SoftBodyClusterData + { + public: + btTransformFloatData m_framexform; + btMatrix3x3FloatData m_locii; + btMatrix3x3FloatData m_invwi; + btVector3FloatData m_com; + btVector3FloatData m_vimpulses[2]; + btVector3FloatData m_dimpulses[2]; + btVector3FloatData m_lv; + btVector3FloatData m_av; + btVector3FloatData *m_framerefs; + int *m_nodeIndices; + float *m_masses; + int m_numFrameRefs; + int m_numNodes; + int m_numMasses; + float m_idmass; + float m_imass; + int m_nvimpulses; + int m_ndimpulses; + float m_ndamping; + float m_ldamping; + float m_adamping; + float m_matching; + float m_maxSelfCollisionImpulse; + float m_selfCollisionImpulseFactor; + int m_containsAnchor; + int m_collide; + int m_clusterIndex; + }; + + +// -------------------------------------------------- // + class btSoftBodyJointData + { + public: + void *m_bodyA; + void *m_bodyB; + btVector3FloatData m_refs[2]; + float m_cfm; + float m_erp; + float m_split; + int m_delete; + btVector3FloatData m_relPosition[2]; + int m_bodyAtype; + int m_bodyBtype; + int m_jointType; + int m_pad; + }; + + +// -------------------------------------------------- // + class btSoftBodyFloatData + { + public: + btCollisionObjectFloatData m_collisionObjectData; + SoftBodyPoseData *m_pose; + SoftBodyMaterialData **m_materials; + SoftBodyNodeData *m_nodes; + SoftBodyLinkData *m_links; + SoftBodyFaceData *m_faces; + SoftBodyTetraData *m_tetrahedra; + SoftRigidAnchorData *m_anchors; + SoftBodyClusterData *m_clusters; + btSoftBodyJointData *m_joints; + int m_numMaterials; + int m_numNodes; + int m_numLinks; + int m_numFaces; + int m_numTetrahedra; + int m_numAnchors; + int m_numClusters; + int m_numJoints; + SoftBodyConfigData m_config; + }; + + +// -------------------------------------------------- // + class btMultiBodyLinkDoubleData + { + public: + btQuaternionDoubleData m_zeroRotParentToThis; + btVector3DoubleData m_parentComToThisPivotOffset; + btVector3DoubleData m_thisPivotToThisComOffset; + btVector3DoubleData m_jointAxisTop[6]; + btVector3DoubleData m_jointAxisBottom[6]; + btVector3DoubleData m_linkInertia; + btVector3DoubleData m_absFrameTotVelocityTop; + btVector3DoubleData m_absFrameTotVelocityBottom; + btVector3DoubleData m_absFrameLocVelocityTop; + btVector3DoubleData m_absFrameLocVelocityBottom; + double m_linkMass; + int m_parentIndex; + int m_jointType; + int m_dofCount; + int m_posVarCount; + double m_jointPos[7]; + double m_jointVel[6]; + double m_jointTorque[6]; + double m_jointDamping; + double m_jointFriction; + double m_jointLowerLimit; + double m_jointUpperLimit; + double m_jointMaxForce; + double m_jointMaxVelocity; + char *m_linkName; + char *m_jointName; + btCollisionObjectDoubleData *m_linkCollider; + char *m_paddingPtr; + }; + + +// -------------------------------------------------- // + class btMultiBodyLinkFloatData + { + public: + btQuaternionFloatData m_zeroRotParentToThis; + btVector3FloatData m_parentComToThisPivotOffset; + btVector3FloatData m_thisPivotToThisComOffset; + btVector3FloatData m_jointAxisTop[6]; + btVector3FloatData m_jointAxisBottom[6]; + btVector3FloatData m_linkInertia; + btVector3FloatData m_absFrameTotVelocityTop; + btVector3FloatData m_absFrameTotVelocityBottom; + btVector3FloatData m_absFrameLocVelocityTop; + btVector3FloatData m_absFrameLocVelocityBottom; + int m_dofCount; + float m_linkMass; + int m_parentIndex; + int m_jointType; + float m_jointPos[7]; + float m_jointVel[6]; + float m_jointTorque[6]; + int m_posVarCount; + float m_jointDamping; + float m_jointFriction; + float m_jointLowerLimit; + float m_jointUpperLimit; + float m_jointMaxForce; + float m_jointMaxVelocity; + char *m_linkName; + char *m_jointName; + btCollisionObjectFloatData *m_linkCollider; + char *m_paddingPtr; + }; + + +// -------------------------------------------------- // + class btMultiBodyDoubleData + { + public: + btVector3DoubleData m_baseWorldPosition; + btQuaternionDoubleData m_baseWorldOrientation; + btVector3DoubleData m_baseLinearVelocity; + btVector3DoubleData m_baseAngularVelocity; + btVector3DoubleData m_baseInertia; + double m_baseMass; + int m_numLinks; + char m_padding[4]; + char *m_baseName; + btMultiBodyLinkDoubleData *m_links; + btCollisionObjectDoubleData *m_baseCollider; + }; + + +// -------------------------------------------------- // + class btMultiBodyFloatData + { + public: + btVector3FloatData m_baseWorldPosition; + btQuaternionFloatData m_baseWorldOrientation; + btVector3FloatData m_baseLinearVelocity; + btVector3FloatData m_baseAngularVelocity; + btVector3FloatData m_baseInertia; + float m_baseMass; + int m_numLinks; + char *m_baseName; + btMultiBodyLinkFloatData *m_links; + btCollisionObjectFloatData *m_baseCollider; + }; + + +// -------------------------------------------------- // + class btMultiBodyLinkColliderFloatData + { + public: + btCollisionObjectFloatData m_colObjData; + btMultiBodyFloatData *m_multiBody; + int m_link; + char m_padding[4]; + }; + + +// -------------------------------------------------- // + class btMultiBodyLinkColliderDoubleData + { + public: + btCollisionObjectDoubleData m_colObjData; + btMultiBodyDoubleData *m_multiBody; + int m_link; + char m_padding[4]; + }; + + +} +#endif//__BULLET_H__ \ No newline at end of file diff --git a/extern/bullet3/Serialize/BulletFileLoader/bChunk.cpp b/extern/bullet3/Serialize/BulletFileLoader/bChunk.cpp new file mode 100644 index 0000000..316c11a --- /dev/null +++ b/extern/bullet3/Serialize/BulletFileLoader/bChunk.cpp @@ -0,0 +1,69 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. 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. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "bChunk.h" +#include "bDefines.h" +#include "bFile.h" + +#if !defined(__CELLOS_LV2__) && !defined(__MWERKS__) +#include +#endif +#include + +using namespace bParse; + +// ----------------------------------------------------- // +short ChunkUtils::swapShort(short sht) +{ + SWITCH_SHORT(sht); + return sht; +} + +// ----------------------------------------------------- // +int ChunkUtils::swapInt(int inte) +{ + SWITCH_INT(inte); + return inte; +} + +// ----------------------------------------------------- // +long64 ChunkUtils::swapLong64(long64 lng) +{ + SWITCH_LONGINT(lng); + return lng; +} + +// ----------------------------------------------------- // +int ChunkUtils::getOffset(int flags) +{ + // if the file is saved in a + // different format, get the + // file's chunk size + int res = CHUNK_HEADER_LEN; + + if (VOID_IS_8) + { + if (flags & FD_BITS_VARIES) + res = sizeof(bChunkPtr4); + } + else + { + if (flags & FD_BITS_VARIES) + res = sizeof(bChunkPtr8); + } + return res; +} + +//eof diff --git a/extern/bullet3/Serialize/BulletFileLoader/bChunk.h b/extern/bullet3/Serialize/BulletFileLoader/bChunk.h new file mode 100644 index 0000000..514a35a --- /dev/null +++ b/extern/bullet3/Serialize/BulletFileLoader/bChunk.h @@ -0,0 +1,84 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. 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. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef __BCHUNK_H__ +#define __BCHUNK_H__ + +#if defined(_WIN32) && !defined(__MINGW32__) +#define long64 __int64 +#elif defined(__MINGW32__) +#include +#define long64 int64_t +#else +#define long64 long long +#endif + +namespace bParse +{ +// ----------------------------------------------------- // +class bChunkPtr4 +{ +public: + bChunkPtr4() {} + int code; + int len; + union { + int m_uniqueInt; + }; + int dna_nr; + int nr; +}; + +// ----------------------------------------------------- // +class bChunkPtr8 +{ +public: + bChunkPtr8() {} + int code, len; + union { + long64 oldPrev; + int m_uniqueInts[2]; + }; + int dna_nr, nr; +}; + +// ----------------------------------------------------- // +class bChunkInd +{ +public: + bChunkInd() {} + int code, len; + void *oldPtr; + int dna_nr, nr; +}; + +// ----------------------------------------------------- // +class ChunkUtils +{ +public: + // file chunk offset + static int getOffset(int flags); + + // endian utils + static short swapShort(short sht); + static int swapInt(int inte); + static long64 swapLong64(long64 lng); +}; + +const int CHUNK_HEADER_LEN = ((sizeof(bChunkInd))); +const bool VOID_IS_8 = ((sizeof(void *) == 8)); +} // namespace bParse + +#endif //__BCHUNK_H__ diff --git a/extern/bullet3/Serialize/BulletFileLoader/bCommon.h b/extern/bullet3/Serialize/BulletFileLoader/bCommon.h new file mode 100644 index 0000000..a3f599f --- /dev/null +++ b/extern/bullet3/Serialize/BulletFileLoader/bCommon.h @@ -0,0 +1,40 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. 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. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef __BCOMMON_H__ +#define __BCOMMON_H__ + +#include +//#include "bLog.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btHashMap.h" + +namespace bParse +{ +class bMain; +class bFileData; +class bFile; +class bDNA; + +// delete void* undefined +typedef struct bStructHandle +{ + int unused; +} bStructHandle; +typedef btAlignedObjectArray bListBasePtr; +typedef btHashMap bPtrMap; +} // namespace bParse + +#endif //__BCOMMON_H__ diff --git a/extern/bullet3/Serialize/BulletFileLoader/bDNA.cpp b/extern/bullet3/Serialize/BulletFileLoader/bDNA.cpp new file mode 100644 index 0000000..8d581d2 --- /dev/null +++ b/extern/bullet3/Serialize/BulletFileLoader/bDNA.cpp @@ -0,0 +1,617 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. 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. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#include + +#include "bDNA.h" +#include "bChunk.h" +#include +#include +#include + +//this define will force traversal of structures, to check backward (and forward) compatibility +//#define TEST_BACKWARD_FORWARD_COMPATIBILITY + +using namespace bParse; + +// ----------------------------------------------------- // +bDNA::bDNA() + : mPtrLen(0) +{ + // -- +} + +// ----------------------------------------------------- // +bDNA::~bDNA() +{ + // -- +} + +// ----------------------------------------------------- // +bool bDNA::lessThan(bDNA *file) +{ + return (m_Names.size() < file->m_Names.size()); +} + +// ----------------------------------------------------- // +char *bDNA::getName(int ind) +{ + assert(ind <= (int)m_Names.size()); + return m_Names[ind].m_name; +} + +// ----------------------------------------------------- // +char *bDNA::getType(int ind) +{ + assert(ind <= (int)mTypes.size()); + return mTypes[ind]; +} + +// ----------------------------------------------------- // +short *bDNA::getStruct(int ind) +{ + assert(ind <= (int)mStructs.size()); + return mStructs[ind]; +} + +// ----------------------------------------------------- // +short bDNA::getLength(int ind) +{ + assert(ind <= (int)mTlens.size()); + return mTlens[ind]; +} + +// ----------------------------------------------------- // +int bDNA::getReverseType(short type) +{ + int *intPtr = mStructReverse.find(type); + if (intPtr) + return *intPtr; + + return -1; +} + +// ----------------------------------------------------- // +int bDNA::getReverseType(const char *type) +{ + btHashString key(type); + int *valuePtr = mTypeLookup.find(key); + if (valuePtr) + return *valuePtr; + + return -1; +} + +// ----------------------------------------------------- // +int bDNA::getNumStructs() +{ + return (int)mStructs.size(); +} + +// ----------------------------------------------------- // +bool bDNA::flagNotEqual(int dna_nr) +{ + assert(dna_nr <= (int)mCMPFlags.size()); + return mCMPFlags[dna_nr] == FDF_STRUCT_NEQU; +} + +// ----------------------------------------------------- // +bool bDNA::flagEqual(int dna_nr) +{ + assert(dna_nr <= (int)mCMPFlags.size()); + int flag = mCMPFlags[dna_nr]; + return flag == FDF_STRUCT_EQU; +} + +// ----------------------------------------------------- // +bool bDNA::flagNone(int dna_nr) +{ + assert(dna_nr <= (int)mCMPFlags.size()); + return mCMPFlags[dna_nr] == FDF_NONE; +} + +// ----------------------------------------------------- // +int bDNA::getPointerSize() +{ + return mPtrLen; +} + +// ----------------------------------------------------- // +void bDNA::initRecurseCmpFlags(int iter) +{ + // iter is FDF_STRUCT_NEQU + + short *oldStrc = mStructs[iter]; + short type = oldStrc[0]; + + for (int i = 0; i < (int)mStructs.size(); i++) + { + if (i != iter && mCMPFlags[i] == FDF_STRUCT_EQU) + { + short *curStruct = mStructs[i]; + int eleLen = curStruct[1]; + curStruct += 2; + + for (int j = 0; j < eleLen; j++, curStruct += 2) + { + if (curStruct[0] == type) + { + //char *name = m_Names[curStruct[1]].m_name; + //if (name[0] != '*') + if (m_Names[curStruct[1]].m_isPointer) + { + mCMPFlags[i] = FDF_STRUCT_NEQU; + initRecurseCmpFlags(i); + } + } + } + } + } +} + +// ----------------------------------------------------- // +void bDNA::initCmpFlags(bDNA *memDNA) +{ + // compare the file to memory + // this ptr should be the file data + + assert(!(m_Names.size() == 0)); //DNA empty! + + mCMPFlags.resize(mStructs.size(), FDF_NONE); + + int i; + for (i = 0; i < (int)mStructs.size(); i++) + { + short *oldStruct = mStructs[i]; + + int oldLookup = getReverseType(oldStruct[0]); + if (oldLookup == -1) + { + mCMPFlags[i] = FDF_NONE; + continue; + } + //char* typeName = mTypes[oldStruct[0]]; + +//#define SLOW_FORWARD_COMPATIBLE 1 +#ifdef SLOW_FORWARD_COMPATIBLE + char *typeName = mTypes[oldLookup]; + int newLookup = memDNA->getReverseType(typeName); + if (newLookup == -1) + { + mCMPFlags[i] = FDF_NONE; + continue; + } + short *curStruct = memDNA->mStructs[newLookup]; +#else + // memory for file + + if (oldLookup < memDNA->mStructs.size()) + { + short *curStruct = memDNA->mStructs[oldLookup]; +#endif + + // rebuild... + mCMPFlags[i] = FDF_STRUCT_NEQU; + +#ifndef TEST_BACKWARD_FORWARD_COMPATIBILITY + + if (curStruct[1] == oldStruct[1]) + { + // type len same ... + if (mTlens[oldStruct[0]] == memDNA->mTlens[curStruct[0]]) + { + bool isSame = true; + int elementLength = oldStruct[1]; + + curStruct += 2; + oldStruct += 2; + + for (int j = 0; j < elementLength; j++, curStruct += 2, oldStruct += 2) + { + // type the same + //const char* typeFileDNA = mTypes[oldStruct[0]]; + //const char* typeMemDNA = mTypes[curStruct[0]]; + if (strcmp(mTypes[oldStruct[0]], memDNA->mTypes[curStruct[0]]) != 0) + { + isSame = false; + break; + } + + // name the same + if (strcmp(m_Names[oldStruct[1]].m_name, memDNA->m_Names[curStruct[1]].m_name) != 0) + { + isSame = false; + break; + } + } + // flag valid == + if (isSame) + mCMPFlags[i] = FDF_STRUCT_EQU; + } + } +#endif + } +} + +// recurse in +for (i = 0; i < (int)mStructs.size(); i++) +{ + if (mCMPFlags[i] == FDF_STRUCT_NEQU) + initRecurseCmpFlags(i); +} +} + +static int name_is_array(char *name, int *dim1, int *dim2) +{ + int len = strlen(name); + /*fprintf(stderr,"[%s]",name);*/ + /*if (len >= 1) { + if (name[len-1] != ']') + return 1; + } + return 0;*/ + char *bp; + int num; + if (dim1) + { + *dim1 = 1; + } + if (dim2) + { + *dim2 = 1; + } + bp = strchr(name, '['); + if (!bp) + { + return 0; + } + num = 0; + while (++bp < name + len - 1) + { + const char c = *bp; + if (c == ']') + { + break; + } + if (c <= '9' && c >= '0') + { + num *= 10; + num += (c - '0'); + } + else + { + printf("array parse error.\n"); + return 0; + } + } + if (dim2) + { + *dim2 = num; + } + + /* find second dim, if any. */ + bp = strchr(bp, '['); + if (!bp) + { + return 1; /* at least we got the first dim. */ + } + num = 0; + while (++bp < name + len - 1) + { + const char c = *bp; + if (c == ']') + { + break; + } + if (c <= '9' && c >= '0') + { + num *= 10; + num += (c - '0'); + } + else + { + printf("array2 parse error.\n"); + return 1; + } + } + if (dim1) + { + if (dim2) + { + *dim1 = *dim2; + *dim2 = num; + } + else + { + *dim1 = num; + } + } + + return 1; +} + +// ----------------------------------------------------- // +void bDNA::init(char *data, int len, bool swap) +{ + int *intPtr = 0; + short *shtPtr = 0; + char *cp = 0; + int dataLen = 0; + //long nr=0; + intPtr = (int *)data; + + /* + SDNA (4 bytes) (magic number) + NAME (4 bytes) + (4 bytes) amount of names (int) + + + */ + + if (strncmp(data, "SDNA", 4) == 0) + { + // skip ++ NAME + intPtr++; + intPtr++; + } + + // Parse names + if (swap) + { + *intPtr = ChunkUtils::swapInt(*intPtr); + } + dataLen = *intPtr; + intPtr++; + + cp = (char *)intPtr; + int i; + for (i = 0; i < dataLen; i++) + { + bNameInfo info; + info.m_name = cp; + info.m_isPointer = (info.m_name[0] == '*') || (info.m_name[1] == '*'); + name_is_array(info.m_name, &info.m_dim0, &info.m_dim1); + m_Names.push_back(info); + while (*cp) cp++; + cp++; + } + + cp = btAlignPointer(cp, 4); + + /* + TYPE (4 bytes) + amount of types (int) + + + */ + + intPtr = (int *)cp; + assert(strncmp(cp, "TYPE", 4) == 0); + intPtr++; + + if (swap) + { + *intPtr = ChunkUtils::swapInt(*intPtr); + } + dataLen = *intPtr; + intPtr++; + + cp = (char *)intPtr; + for (i = 0; i < dataLen; i++) + { + mTypes.push_back(cp); + while (*cp) cp++; + cp++; + } + + cp = btAlignPointer(cp, 4); + + /* + TLEN (4 bytes) + (short) the lengths of types + + */ + + // Parse type lens + intPtr = (int *)cp; + assert(strncmp(cp, "TLEN", 4) == 0); + intPtr++; + + dataLen = (int)mTypes.size(); + + shtPtr = (short *)intPtr; + for (i = 0; i < dataLen; i++, shtPtr++) + { + if (swap) + shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]); + mTlens.push_back(shtPtr[0]); + } + + if (dataLen & 1) shtPtr++; + + /* + STRC (4 bytes) + amount of structs (int) + + + + + + + */ + + intPtr = (int *)shtPtr; + cp = (char *)intPtr; + assert(strncmp(cp, "STRC", 4) == 0); + intPtr++; + + if (swap) + { + *intPtr = ChunkUtils::swapInt(*intPtr); + } + dataLen = *intPtr; + intPtr++; + + shtPtr = (short *)intPtr; + for (i = 0; i < dataLen; i++) + { + mStructs.push_back(shtPtr); + if (swap) + { + shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]); + shtPtr[1] = ChunkUtils::swapShort(shtPtr[1]); + + int len = shtPtr[1]; + shtPtr += 2; + + for (int a = 0; a < len; a++, shtPtr += 2) + { + shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]); + shtPtr[1] = ChunkUtils::swapShort(shtPtr[1]); + } + } + else + shtPtr += (2 * shtPtr[1]) + 2; + } + + // build reverse lookups + for (i = 0; i < (int)mStructs.size(); i++) + { + short *strc = mStructs.at(i); + if (!mPtrLen && strcmp(mTypes[strc[0]], "ListBase") == 0) + { + mPtrLen = mTlens[strc[0]] / 2; + } + + mStructReverse.insert(strc[0], i); + mTypeLookup.insert(btHashString(mTypes[strc[0]]), i); + } +} + +// ----------------------------------------------------- // +int bDNA::getArraySize(char *string) +{ + int ret = 1; + int len = strlen(string); + + char *next = 0; + for (int i = 0; i < len; i++) + { + char c = string[i]; + + if (c == '[') + next = &string[i + 1]; + else if (c == ']') + if (next) + ret *= atoi(next); + } + + // print (string << ' ' << ret); + return ret; +} + +void bDNA::dumpTypeDefinitions() +{ + int i; + + int numTypes = mTypes.size(); + + for (i = 0; i < numTypes; i++) + { + } + + for (i = 0; i < (int)mStructs.size(); i++) + { + int totalBytes = 0; + short *oldStruct = mStructs[i]; + + int oldLookup = getReverseType(oldStruct[0]); + if (oldLookup == -1) + { + mCMPFlags[i] = FDF_NONE; + continue; + } + + short *newStruct = mStructs[oldLookup]; + char *typeName = mTypes[newStruct[0]]; + printf("%3d: %s ", i, typeName); + + //char *name = mNames[oldStruct[1]]; + int len = oldStruct[1]; + printf(" (%d fields) ", len); + oldStruct += 2; + + printf("{"); + int j; + for (j = 0; j < len; ++j, oldStruct += 2) + { + const char *name = m_Names[oldStruct[1]].m_name; + printf("%s %s", mTypes[oldStruct[0]], name); + int elemNumBytes = 0; + int arrayDimensions = getArraySizeNew(oldStruct[1]); + + if (m_Names[oldStruct[1]].m_isPointer) + { + elemNumBytes = VOID_IS_8 ? 8 : 4; + } + else + { + elemNumBytes = getLength(oldStruct[0]); + } + printf(" /* %d bytes */", elemNumBytes * arrayDimensions); + + if (j == len - 1) + { + printf(";}"); + } + else + { + printf("; "); + } + totalBytes += elemNumBytes * arrayDimensions; + } + printf("\ntotalBytes=%d\n\n", totalBytes); + } + +#if 0 + /* dump out display of types and their sizes */ + for (i=0; itypes_count; ++i) { + /* if (!bf->types[i].is_struct)*/ + { + printf("%3d: sizeof(%s%s)=%d", + i, + bf->types[i].is_struct ? "struct " : "atomic ", + bf->types[i].name, bf->types[i].size); + if (bf->types[i].is_struct) { + int j; + printf(", %d fields: { ", bf->types[i].fieldtypes_count); + for (j=0; jtypes[i].fieldtypes_count; ++j) { + printf("%s %s", + bf->types[bf->types[i].fieldtypes[j]].name, + bf->names[bf->types[i].fieldnames[j]]); + if (j == bf->types[i].fieldtypes_count-1) { + printf(";}"); + } else { + printf("; "); + } + } + } + printf("\n\n"); + + } + } +#endif +} + +//eof diff --git a/extern/bullet3/Serialize/BulletFileLoader/bDNA.h b/extern/bullet3/Serialize/BulletFileLoader/bDNA.h new file mode 100644 index 0000000..4b1c530 --- /dev/null +++ b/extern/bullet3/Serialize/BulletFileLoader/bDNA.h @@ -0,0 +1,101 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. 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. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef __BDNA_H__ +#define __BDNA_H__ + +#include "bCommon.h" + +namespace bParse +{ +struct bNameInfo +{ + char *m_name; + bool m_isPointer; + int m_dim0; + int m_dim1; +}; + +class bDNA +{ +public: + bDNA(); + ~bDNA(); + + void init(char *data, int len, bool swap = false); + + int getArraySize(char *str); + int getArraySizeNew(short name) + { + const bNameInfo &nameInfo = m_Names[name]; + return nameInfo.m_dim0 * nameInfo.m_dim1; + } + int getElementSize(short type, short name) + { + const bNameInfo &nameInfo = m_Names[name]; + int size = nameInfo.m_isPointer ? mPtrLen * nameInfo.m_dim0 * nameInfo.m_dim1 : mTlens[type] * nameInfo.m_dim0 * nameInfo.m_dim1; + return size; + } + + int getNumNames() const + { + return m_Names.size(); + } + + char *getName(int ind); + char *getType(int ind); + short *getStruct(int ind); + short getLength(int ind); + int getReverseType(short type); + int getReverseType(const char *type); + + int getNumStructs(); + + // + bool lessThan(bDNA *other); + + void initCmpFlags(bDNA *memDNA); + bool flagNotEqual(int dna_nr); + bool flagEqual(int dna_nr); + bool flagNone(int dna_nr); + + int getPointerSize(); + + void dumpTypeDefinitions(); + +private: + enum FileDNAFlags + { + FDF_NONE = 0, + FDF_STRUCT_NEQU, + FDF_STRUCT_EQU + }; + + void initRecurseCmpFlags(int i); + + btAlignedObjectArray mCMPFlags; + + btAlignedObjectArray m_Names; + btAlignedObjectArray mTypes; + btAlignedObjectArray mStructs; + btAlignedObjectArray mTlens; + btHashMap mStructReverse; + btHashMap mTypeLookup; + + int mPtrLen; +}; +} // namespace bParse + +#endif //__BDNA_H__ diff --git a/extern/bullet3/Serialize/BulletFileLoader/bDefines.h b/extern/bullet3/Serialize/BulletFileLoader/bDefines.h new file mode 100644 index 0000000..c5ad20a --- /dev/null +++ b/extern/bullet3/Serialize/BulletFileLoader/bDefines.h @@ -0,0 +1,152 @@ +/* Copyright (C) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. 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. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef __B_DEFINES_H__ +#define __B_DEFINES_H__ + +// MISC defines, see BKE_global.h, BKE_utildefines.h +#define SIZEOFBLENDERHEADER 12 + +// ------------------------------------------------------------ +#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined(__PPC__) || defined(__ppc__) || defined(__BIG_ENDIAN__) +#define MAKE_ID(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d)) +#else +#define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a)) +#endif + +// ------------------------------------------------------------ +#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined(__PPC__) || defined(__ppc__) || defined(__BIG_ENDIAN__) +#define MAKE_ID2(c, d) ((c) << 8 | (d)) +#define MOST_SIG_BYTE 0 +#define BBIG_ENDIAN +#else +#define MAKE_ID2(c, d) ((d) << 8 | (c)) +#define MOST_SIG_BYTE 1 +#define BLITTLE_ENDIAN +#endif + +// ------------------------------------------------------------ +#define ID_SCE MAKE_ID2('S', 'C') +#define ID_LI MAKE_ID2('L', 'I') +#define ID_OB MAKE_ID2('O', 'B') +#define ID_ME MAKE_ID2('M', 'E') +#define ID_CU MAKE_ID2('C', 'U') +#define ID_MB MAKE_ID2('M', 'B') +#define ID_MA MAKE_ID2('M', 'A') +#define ID_TE MAKE_ID2('T', 'E') +#define ID_IM MAKE_ID2('I', 'M') +#define ID_IK MAKE_ID2('I', 'K') +#define ID_WV MAKE_ID2('W', 'V') +#define ID_LT MAKE_ID2('L', 'T') +#define ID_SE MAKE_ID2('S', 'E') +#define ID_LF MAKE_ID2('L', 'F') +#define ID_LA MAKE_ID2('L', 'A') +#define ID_CA MAKE_ID2('C', 'A') +#define ID_IP MAKE_ID2('I', 'P') +#define ID_KE MAKE_ID2('K', 'E') +#define ID_WO MAKE_ID2('W', 'O') +#define ID_SCR MAKE_ID2('S', 'R') +#define ID_VF MAKE_ID2('V', 'F') +#define ID_TXT MAKE_ID2('T', 'X') +#define ID_SO MAKE_ID2('S', 'O') +#define ID_SAMPLE MAKE_ID2('S', 'A') +#define ID_GR MAKE_ID2('G', 'R') +#define ID_ID MAKE_ID2('I', 'D') +#define ID_AR MAKE_ID2('A', 'R') +#define ID_AC MAKE_ID2('A', 'C') +#define ID_SCRIPT MAKE_ID2('P', 'Y') +#define ID_FLUIDSIM MAKE_ID2('F', 'S') +#define ID_NT MAKE_ID2('N', 'T') +#define ID_BR MAKE_ID2('B', 'R') + +#define ID_SEQ MAKE_ID2('S', 'Q') +#define ID_CO MAKE_ID2('C', 'O') +#define ID_PO MAKE_ID2('A', 'C') +#define ID_NLA MAKE_ID2('N', 'L') + +#define ID_VS MAKE_ID2('V', 'S') +#define ID_VN MAKE_ID2('V', 'N') + +// ------------------------------------------------------------ +#define FORM MAKE_ID('F', 'O', 'R', 'M') +#define DDG1 MAKE_ID('3', 'D', 'G', '1') +#define DDG2 MAKE_ID('3', 'D', 'G', '2') +#define DDG3 MAKE_ID('3', 'D', 'G', '3') +#define DDG4 MAKE_ID('3', 'D', 'G', '4') +#define GOUR MAKE_ID('G', 'O', 'U', 'R') +#define BLEN MAKE_ID('B', 'L', 'E', 'N') +#define DER_ MAKE_ID('D', 'E', 'R', '_') +#define V100 MAKE_ID('V', '1', '0', '0') +#define DATA MAKE_ID('D', 'A', 'T', 'A') +#define GLOB MAKE_ID('G', 'L', 'O', 'B') +#define IMAG MAKE_ID('I', 'M', 'A', 'G') +#define USER MAKE_ID('U', 'S', 'E', 'R') + +// ------------------------------------------------------------ +#define DNA1 MAKE_ID('D', 'N', 'A', '1') +#define REND MAKE_ID('R', 'E', 'N', 'D') +#define ENDB MAKE_ID('E', 'N', 'D', 'B') +#define NAME MAKE_ID('N', 'A', 'M', 'E') +#define SDNA MAKE_ID('S', 'D', 'N', 'A') +#define TYPE MAKE_ID('T', 'Y', 'P', 'E') +#define TLEN MAKE_ID('T', 'L', 'E', 'N') +#define STRC MAKE_ID('S', 'T', 'R', 'C') + +// ------------------------------------------------------------ +#define SWITCH_INT(a) \ + { \ + char s_i, *p_i; \ + p_i = (char *)&(a); \ + s_i = p_i[0]; \ + p_i[0] = p_i[3]; \ + p_i[3] = s_i; \ + s_i = p_i[1]; \ + p_i[1] = p_i[2]; \ + p_i[2] = s_i; \ + } + +// ------------------------------------------------------------ +#define SWITCH_SHORT(a) \ + { \ + char s_i, *p_i; \ + p_i = (char *)&(a); \ + s_i = p_i[0]; \ + p_i[0] = p_i[1]; \ + p_i[1] = s_i; \ + } + +// ------------------------------------------------------------ +#define SWITCH_LONGINT(a) \ + { \ + char s_i, *p_i; \ + p_i = (char *)&(a); \ + s_i = p_i[0]; \ + p_i[0] = p_i[7]; \ + p_i[7] = s_i; \ + s_i = p_i[1]; \ + p_i[1] = p_i[6]; \ + p_i[6] = s_i; \ + s_i = p_i[2]; \ + p_i[2] = p_i[5]; \ + p_i[5] = s_i; \ + s_i = p_i[3]; \ + p_i[3] = p_i[4]; \ + p_i[4] = s_i; \ + } + +#endif //__B_DEFINES_H__ diff --git a/extern/bullet3/Serialize/BulletFileLoader/bFile.cpp b/extern/bullet3/Serialize/BulletFileLoader/bFile.cpp new file mode 100644 index 0000000..5f19dd5 --- /dev/null +++ b/extern/bullet3/Serialize/BulletFileLoader/bFile.cpp @@ -0,0 +1,1686 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. 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. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#include "bFile.h" +#include "bCommon.h" +#include "bChunk.h" +#include "bDNA.h" +#include +#include +#include +#include "bDefines.h" +#include "LinearMath/btSerializer.h" +#include "LinearMath/btAlignedAllocator.h" +#include "LinearMath/btMinMax.h" + +#define SIZEOFBLENDERHEADER 12 +#define MAX_ARRAY_LENGTH 512 +using namespace bParse; +#define MAX_STRLEN 1024 + +const char *getCleanName(const char *memName, char *buffer) +{ + int slen = strlen(memName); + assert(slen < MAX_STRLEN); + slen = btMin(slen, MAX_STRLEN); + for (int i = 0; i < slen; i++) + { + if (memName[i] == ']' || memName[i] == '[') + { + buffer[i] = 0; //'_'; + } + else + { + buffer[i] = memName[i]; + } + } + buffer[slen] = 0; + return buffer; +} + +int numallocs = 0; + +// ----------------------------------------------------- // +bFile::bFile(const char *filename, const char headerString[7]) + : mOwnsBuffer(true), + mFileBuffer(0), + mFileLen(0), + mVersion(0), + mDataStart(0), + mFileDNA(0), + mMemoryDNA(0), + mFlags(FD_INVALID) +{ + for (int i = 0; i < 7; i++) + { + m_headerString[i] = headerString[i]; + } + + FILE *fp = fopen(filename, "rb"); + if (fp) + { + fseek(fp, 0L, SEEK_END); + mFileLen = ftell(fp); + fseek(fp, 0L, SEEK_SET); + + mFileBuffer = (char *)malloc(mFileLen + 1); + memset(mFileBuffer, 0, mFileLen+1); + size_t bytesRead; + bytesRead = fread(mFileBuffer, mFileLen, 1, fp); + + fclose(fp); + + // + parseHeader(); + } +} + +// ----------------------------------------------------- // +bFile::bFile(char *memoryBuffer, int len, const char headerString[7]) + : mOwnsBuffer(false), + mFileBuffer(0), + mFileLen(0), + mVersion(0), + mDataStart(0), + mFileDNA(0), + mMemoryDNA(0), + mFlags(FD_INVALID) +{ + for (int i = 0; i < 7; i++) + { + m_headerString[i] = headerString[i]; + } + mFileBuffer = memoryBuffer; + mFileLen = len; + + parseHeader(); +} + +// ----------------------------------------------------- // +bFile::~bFile() +{ + if (mOwnsBuffer && mFileBuffer) + { + free(mFileBuffer); + mFileBuffer = 0; + } + + delete mMemoryDNA; + delete mFileDNA; +} + +// ----------------------------------------------------- // +void bFile::parseHeader() +{ + if (!mFileLen || !mFileBuffer) + return; + + char *blenderBuf = mFileBuffer; + char header[SIZEOFBLENDERHEADER + 1]; + memcpy(header, blenderBuf, SIZEOFBLENDERHEADER); + header[SIZEOFBLENDERHEADER] = '\0'; + + if (strncmp(header, m_headerString, 6) != 0) + { + memcpy(header, m_headerString, SIZEOFBLENDERHEADER); + return; + } + + if (header[6] == 'd') + { + mFlags |= FD_DOUBLE_PRECISION; + } + + char *ver = header + 9; + mVersion = atoi(ver); + if (mVersion <= 241) + { + //printf("Warning, %d not fully tested : <= 242\n", mVersion); + } + + int littleEndian = 1; + littleEndian = ((char *)&littleEndian)[0]; + + // swap ptr sizes... + if (header[7] == '-') + { + mFlags |= FD_FILE_64; + if (!VOID_IS_8) + mFlags |= FD_BITS_VARIES; + } + else if (VOID_IS_8) + mFlags |= FD_BITS_VARIES; + + // swap endian... + if (header[8] == 'V') + { + if (littleEndian == 1) + mFlags |= FD_ENDIAN_SWAP; + } + else if (littleEndian == 0) + mFlags |= FD_ENDIAN_SWAP; + + mFlags |= FD_OK; +} + +// ----------------------------------------------------- // +bool bFile::ok() +{ + return (mFlags & FD_OK) != 0; +} + +void bFile::setFileDNA(int verboseMode, char *dnaBuffer, int dnaLen) +{ + mFileDNA = new bDNA(); + + ///mFileDNA->init will convert part of DNA file endianness to current CPU endianness if necessary + mFileDNA->init((char *)dnaBuffer, dnaLen, (mFlags & FD_ENDIAN_SWAP) != 0); + + if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS) + mFileDNA->dumpTypeDefinitions(); +} + +// ----------------------------------------------------- // +void bFile::parseInternal(int verboseMode, char *memDna, int memDnaLength) +{ + if ((mFlags & FD_OK) == 0) + return; + + if (mFlags & FD_FILEDNA_IS_MEMDNA) + { + setFileDNA(verboseMode, memDna, memDnaLength); + } + + if (mFileDNA == 0) + { + char *blenderData = mFileBuffer; + bChunkInd dna; + dna.oldPtr = 0; + + char *tempBuffer = blenderData; + for (int i = 0; i < mFileLen; i++) + { + // looking for the data's starting position + // and the start of SDNA decls + + if (!mDataStart && strncmp(tempBuffer, "REND", 4) == 0) + mDataStart = i; + + if (strncmp(tempBuffer, "DNA1", 4) == 0) + { + // read the DNA1 block and extract SDNA + if (getNextBlock(&dna, tempBuffer, mFlags) > 0) + { + if (strncmp((tempBuffer + ChunkUtils::getOffset(mFlags)), "SDNANAME", 8) == 0) + dna.oldPtr = (tempBuffer + ChunkUtils::getOffset(mFlags)); + else + dna.oldPtr = 0; + } + else + dna.oldPtr = 0; + } + // Some Bullet files are missing the DNA1 block + // In Blender it's DNA1 + ChunkUtils::getOffset() + SDNA + NAME + // In Bullet tests its SDNA + NAME + else if (strncmp(tempBuffer, "SDNANAME", 8) == 0) + { + dna.oldPtr = blenderData + i; + dna.len = mFileLen - i; + + // Also no REND block, so exit now. + if (mVersion == 276) break; + } + + if (mDataStart && dna.oldPtr) break; + tempBuffer++; + } + if (!dna.oldPtr || !dna.len) + { + //printf("Failed to find DNA1+SDNA pair\n"); + mFlags &= ~FD_OK; + return; + } + + mFileDNA = new bDNA(); + + ///mFileDNA->init will convert part of DNA file endianness to current CPU endianness if necessary + mFileDNA->init((char *)dna.oldPtr, dna.len, (mFlags & FD_ENDIAN_SWAP) != 0); + + if (mVersion == 276) + { + int i; + for (i = 0; i < mFileDNA->getNumNames(); i++) + { + if (strcmp(mFileDNA->getName(i), "int") == 0) + { + mFlags |= FD_BROKEN_DNA; + } + } + if ((mFlags & FD_BROKEN_DNA) != 0) + { + //printf("warning: fixing some broken DNA version\n"); + } + } + + if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS) + mFileDNA->dumpTypeDefinitions(); + } + mMemoryDNA = new bDNA(); + int littleEndian = 1; + littleEndian = ((char *)&littleEndian)[0]; + + mMemoryDNA->init(memDna, memDnaLength, littleEndian == 0); + + ///@todo we need a better version check, add version/sub version info from FileGlobal into memory DNA/header files + if (mMemoryDNA->getNumNames() != mFileDNA->getNumNames()) + { + mFlags |= FD_VERSION_VARIES; + //printf ("Warning, file DNA is different than built in, performance is reduced. Best to re-export file with a matching version/platform"); + } + + // as long as it kept up to date it will be ok!! + if (mMemoryDNA->lessThan(mFileDNA)) + { + //printf ("Warning, file DNA is newer than built in."); + } + + mFileDNA->initCmpFlags(mMemoryDNA); + + parseData(); + + resolvePointers(verboseMode); + + updateOldPointers(); +} + +// ----------------------------------------------------- // +void bFile::swap(char *head, bChunkInd &dataChunk, bool ignoreEndianFlag) +{ + char *data = head; + short *strc = mFileDNA->getStruct(dataChunk.dna_nr); + + const char s[] = "SoftBodyMaterialData"; + int szs = sizeof(s); + if (strncmp((char *)&dataChunk.code, "ARAY", 4) == 0) + { + short *oldStruct = mFileDNA->getStruct(dataChunk.dna_nr); + char *oldType = mFileDNA->getType(oldStruct[0]); + if (strncmp(oldType, s, szs) == 0) + { + return; + } + } + + int len = mFileDNA->getLength(strc[0]); + + for (int i = 0; i < dataChunk.nr; i++) + { + swapStruct(dataChunk.dna_nr, data, ignoreEndianFlag); + data += len; + } +} + +void bFile::swapLen(char *dataPtr) +{ + const bool VOID_IS_8 = ((sizeof(void *) == 8)); + if (VOID_IS_8) + { + if (mFlags & FD_BITS_VARIES) + { + bChunkPtr4 *c = (bChunkPtr4 *)dataPtr; + if ((c->code & 0xFFFF) == 0) + c->code >>= 16; + SWITCH_INT(c->len); + SWITCH_INT(c->dna_nr); + SWITCH_INT(c->nr); + } + else + { + bChunkPtr8 *c = (bChunkPtr8 *)dataPtr; + if ((c->code & 0xFFFF) == 0) + c->code >>= 16; + SWITCH_INT(c->len); + SWITCH_INT(c->dna_nr); + SWITCH_INT(c->nr); + } + } + else + { + if (mFlags & FD_BITS_VARIES) + { + bChunkPtr8 *c = (bChunkPtr8 *)dataPtr; + if ((c->code & 0xFFFF) == 0) + c->code >>= 16; + SWITCH_INT(c->len); + SWITCH_INT(c->dna_nr); + SWITCH_INT(c->nr); + } + else + { + bChunkPtr4 *c = (bChunkPtr4 *)dataPtr; + if ((c->code & 0xFFFF) == 0) + c->code >>= 16; + SWITCH_INT(c->len); + + SWITCH_INT(c->dna_nr); + SWITCH_INT(c->nr); + } + } +} + +void bFile::swapDNA(char *ptr) +{ + bool swap = ((mFlags & FD_ENDIAN_SWAP) != 0); + + int offset = (mFlags & FD_FILE_64) ? 24 : 20; + char *data = &ptr[offset]; + + // void bDNA::init(char *data, int len, bool swap) + int *intPtr = 0; + short *shtPtr = 0; + char *cp = 0; + int dataLen = 0; + intPtr = (int *)data; + + /* + SDNA (4 bytes) (magic number) + NAME (4 bytes) + (4 bytes) amount of names (int) + + + */ + + if (strncmp(data, "SDNA", 4) == 0) + { + // skip ++ NAME + intPtr++; + intPtr++; + } + else + { + if (strncmp(data + 4, "SDNA", 4) == 0) + { + // skip ++ NAME + intPtr++; + intPtr++; + intPtr++; + } + } + + // Parse names + if (swap) + dataLen = ChunkUtils::swapInt(*intPtr); + else + dataLen = *intPtr; + + *intPtr = ChunkUtils::swapInt(*intPtr); + intPtr++; + + cp = (char *)intPtr; + int i; + for (i = 0; i < dataLen; i++) + { + while (*cp) cp++; + cp++; + } + + cp = btAlignPointer(cp, 4); + + /* + TYPE (4 bytes) + amount of types (int) + + + */ + + intPtr = (int *)cp; + assert(strncmp(cp, "TYPE", 4) == 0); + intPtr++; + + if (swap) + dataLen = ChunkUtils::swapInt(*intPtr); + else + dataLen = *intPtr; + + *intPtr = ChunkUtils::swapInt(*intPtr); + + intPtr++; + + cp = (char *)intPtr; + for (i = 0; i < dataLen; i++) + { + while (*cp) cp++; + cp++; + } + + cp = btAlignPointer(cp, 4); + + /* + TLEN (4 bytes) + (short) the lengths of types + + */ + + // Parse type lens + intPtr = (int *)cp; + assert(strncmp(cp, "TLEN", 4) == 0); + intPtr++; + + shtPtr = (short *)intPtr; + for (i = 0; i < dataLen; i++, shtPtr++) + { + //??????if (swap) + shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]); + } + + if (dataLen & 1) + shtPtr++; + + /* + STRC (4 bytes) + amount of structs (int) + + + + + + + */ + + intPtr = (int *)shtPtr; + cp = (char *)intPtr; + assert(strncmp(cp, "STRC", 4) == 0); + intPtr++; + + if (swap) + dataLen = ChunkUtils::swapInt(*intPtr); + else + dataLen = *intPtr; + + *intPtr = ChunkUtils::swapInt(*intPtr); + + intPtr++; + + shtPtr = (short *)intPtr; + for (i = 0; i < dataLen; i++) + { + //if (swap) + { + int len = shtPtr[1]; + + shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]); + shtPtr[1] = ChunkUtils::swapShort(shtPtr[1]); + + shtPtr += 2; + + for (int a = 0; a < len; a++, shtPtr += 2) + { + shtPtr[0] = ChunkUtils::swapShort(shtPtr[0]); + shtPtr[1] = ChunkUtils::swapShort(shtPtr[1]); + } + } + // else + // shtPtr+= (2*shtPtr[1])+2; + } +} + +void bFile::writeFile(const char *fileName) +{ + FILE *f = fopen(fileName, "wb"); + fwrite(mFileBuffer, 1, mFileLen, f); + fclose(f); +} + +void bFile::preSwap() +{ + //const bool brokenDNA = (mFlags&FD_BROKEN_DNA)!=0; + //FD_ENDIAN_SWAP + //byte 8 determines the endianness of the file, little (v) versus big (V) + int littleEndian = 1; + littleEndian = ((char *)&littleEndian)[0]; + + if (mFileBuffer[8] == 'V') + { + mFileBuffer[8] = 'v'; + } + else + { + mFileBuffer[8] = 'V'; + } + + mDataStart = 12; + + char *dataPtr = mFileBuffer + mDataStart; + + bChunkInd dataChunk; + dataChunk.code = 0; + bool ignoreEndianFlag = true; + + //we always want to swap here + + int seek = getNextBlock(&dataChunk, dataPtr, mFlags); + //dataPtr += ChunkUtils::getOffset(mFlags); + char *dataPtrHead = 0; + + while (1) + { + // one behind + if (dataChunk.code == SDNA || dataChunk.code == DNA1 || dataChunk.code == TYPE || dataChunk.code == TLEN || dataChunk.code == STRC) + { + swapDNA(dataPtr); + break; + } + else + { + //if (dataChunk.code == DNA1) break; + dataPtrHead = dataPtr + ChunkUtils::getOffset(mFlags); + + swapLen(dataPtr); + if (dataChunk.dna_nr >= 0) + { + swap(dataPtrHead, dataChunk, ignoreEndianFlag); + } + else + { + //printf("unknown chunk\n"); + } + } + + // next please! + dataPtr += seek; + + seek = getNextBlock(&dataChunk, dataPtr, mFlags); + if (seek < 0) + break; + } + + if (mFlags & FD_ENDIAN_SWAP) + { + mFlags &= ~FD_ENDIAN_SWAP; + } + else + { + mFlags |= FD_ENDIAN_SWAP; + } +} + +// ----------------------------------------------------- // +char *bFile::readStruct(char *head, bChunkInd &dataChunk) +{ + bool ignoreEndianFlag = false; + + if (mFlags & FD_ENDIAN_SWAP) + swap(head, dataChunk, ignoreEndianFlag); + + if (!mFileDNA->flagEqual(dataChunk.dna_nr)) + { + // Ouch! need to rebuild the struct + short *oldStruct, *curStruct; + char *oldType, *newType; + int oldLen, curLen, reverseOld; + + oldStruct = mFileDNA->getStruct(dataChunk.dna_nr); + oldType = mFileDNA->getType(oldStruct[0]); + + oldLen = mFileDNA->getLength(oldStruct[0]); + + if ((mFlags & FD_BROKEN_DNA) != 0) + { + if ((strcmp(oldType, "btQuantizedBvhNodeData") == 0) && oldLen == 20) + { + return 0; + } + if ((strcmp(oldType, "btShortIntIndexData") == 0)) + { + int allocLen = 2; + char *dataAlloc = new char[(dataChunk.nr * allocLen) + sizeof(void*)]; + memset(dataAlloc, 0, (dataChunk.nr * allocLen) + sizeof(void*)); + short *dest = (short *)dataAlloc; + const short *src = (short *)head; + for (int i = 0; i < dataChunk.nr; i++) + { + dest[i] = src[i]; + if (mFlags & FD_ENDIAN_SWAP) + { + SWITCH_SHORT(dest[i]); + } + } + addDataBlock(dataAlloc); + return dataAlloc; + } + } + + ///don't try to convert Link block data, just memcpy it. Other data can be converted. + if (strcmp("Link", oldType) != 0) + { + reverseOld = mMemoryDNA->getReverseType(oldType); + + if ((reverseOld != -1)) + { + // make sure it's here + //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!"); + + // + curStruct = mMemoryDNA->getStruct(reverseOld); + newType = mMemoryDNA->getType(curStruct[0]); + curLen = mMemoryDNA->getLength(curStruct[0]); + + // make sure it's the same + assert((strcmp(oldType, newType) == 0) && "internal error, struct mismatch!"); + + numallocs++; + // numBlocks * length + + int allocLen = (curLen); + char *dataAlloc = new char[(dataChunk.nr * allocLen) + sizeof(void*)]; + memset(dataAlloc, 0, (dataChunk.nr * allocLen) + sizeof(void*)); + + // track allocated + addDataBlock(dataAlloc); + + char *cur = dataAlloc; + char *old = head; + for (int block = 0; block < dataChunk.nr; block++) + { + bool fixupPointers = true; + parseStruct(cur, old, dataChunk.dna_nr, reverseOld, fixupPointers); + mLibPointers.insert(old, (bStructHandle *)cur); + + cur += curLen; + old += oldLen; + } + return dataAlloc; + } + } + else + { + //printf("Link found\n"); + } + } + else + { +//#define DEBUG_EQUAL_STRUCTS +#ifdef DEBUG_EQUAL_STRUCTS + short *oldStruct; + char *oldType; + oldStruct = mFileDNA->getStruct(dataChunk.dna_nr); + oldType = mFileDNA->getType(oldStruct[0]); + printf("%s equal structure, just memcpy\n", oldType); +#endif // + } + + char *dataAlloc = new char[(dataChunk.len) + sizeof(void*)]; + memset(dataAlloc, 0, dataChunk.len + sizeof(void*)); + + // track allocated + addDataBlock(dataAlloc); + + memcpy(dataAlloc, head, dataChunk.len); + return dataAlloc; +} + +// ----------------------------------------------------- // +void bFile::parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers) +{ + if (old_dna == -1) return; + if (new_dna == -1) return; + + //disable this, because we need to fixup pointers/ListBase + if (/* DISABLES CODE */ (0)) //mFileDNA->flagEqual(old_dna)) + { + short *strc = mFileDNA->getStruct(old_dna); + int len = mFileDNA->getLength(strc[0]); + + memcpy(strcPtr, dtPtr, len); + return; + } + + // Ok, now build the struct + char *memType, *memName, *cpc, *cpo; + short *fileStruct, *filePtrOld, *memoryStruct, *firstStruct; + int elementLength, size, revType, old_nr, new_nr, fpLen; + short firstStructType; + + // File to memory lookup + memoryStruct = mMemoryDNA->getStruct(new_dna); + fileStruct = mFileDNA->getStruct(old_dna); + firstStruct = fileStruct; + + filePtrOld = fileStruct; + firstStructType = mMemoryDNA->getStruct(0)[0]; + + // Get number of elements + elementLength = memoryStruct[1]; + memoryStruct += 2; + + cpc = strcPtr; + cpo = 0; + for (int ele = 0; ele < elementLength; ele++, memoryStruct += 2) + { + memType = mMemoryDNA->getType(memoryStruct[0]); + memName = mMemoryDNA->getName(memoryStruct[1]); + + size = mMemoryDNA->getElementSize(memoryStruct[0], memoryStruct[1]); + revType = mMemoryDNA->getReverseType(memoryStruct[0]); + + if (revType != -1 && memoryStruct[0] >= firstStructType && memName[0] != '*') + { + cpo = getFileElement(firstStruct, memName, memType, dtPtr, &filePtrOld); + if (cpo) + { + int arrayLen = mFileDNA->getArraySizeNew(filePtrOld[1]); + old_nr = mFileDNA->getReverseType(memType); + new_nr = revType; + fpLen = mFileDNA->getElementSize(filePtrOld[0], filePtrOld[1]); + if (arrayLen == 1) + { + parseStruct(cpc, cpo, old_nr, new_nr, fixupPointers); + } + else + { + char *tmpCpc = cpc; + char *tmpCpo = cpo; + + for (int i = 0; i < arrayLen; i++) + { + parseStruct(tmpCpc, tmpCpo, old_nr, new_nr, fixupPointers); + tmpCpc += size / arrayLen; + tmpCpo += fpLen / arrayLen; + } + } + cpc += size; + cpo += fpLen; + } + else + cpc += size; + } + else + { + getMatchingFileDNA(fileStruct, memName, memType, cpc, dtPtr, fixupPointers); + cpc += size; + } + } +} + +// ----------------------------------------------------- // +static void getElement(int arrayLen, const char *cur, const char *old, char *oldPtr, char *curData) +{ +#define getEle(value, current, type, cast, size, ptr) \ + if (strcmp(current, type) == 0) \ + { \ + value = (*(cast *)ptr); \ + ptr += size; \ + } + +#define setEle(value, current, type, cast, size, ptr) \ + if (strcmp(current, type) == 0) \ + { \ + (*(cast *)ptr) = (cast)value; \ + ptr += size; \ + } + double value = 0.0; + + for (int i = 0; i < arrayLen; i++) + { + getEle(value, old, "char", char, sizeof(char), oldPtr); + setEle(value, cur, "char", char, sizeof(char), curData); + getEle(value, old, "short", short, sizeof(short), oldPtr); + setEle(value, cur, "short", short, sizeof(short), curData); + getEle(value, old, "ushort", unsigned short, sizeof(unsigned short), oldPtr); + setEle(value, cur, "ushort", unsigned short, sizeof(unsigned short), curData); + getEle(value, old, "int", int, sizeof(int), oldPtr); + setEle(value, cur, "int", int, sizeof(int), curData); + getEle(value, old, "long", int, sizeof(int), oldPtr); + setEle(value, cur, "long", int, sizeof(int), curData); + getEle(value, old, "float", float, sizeof(float), oldPtr); + setEle(value, cur, "float", float, sizeof(float), curData); + getEle(value, old, "double", double, sizeof(double), oldPtr); + setEle(value, cur, "double", double, sizeof(double), curData); + } +} + +// ----------------------------------------------------- // +void bFile::swapData(char *data, short type, int arraySize, bool ignoreEndianFlag) +{ + if (ignoreEndianFlag || (mFlags & FD_ENDIAN_SWAP)) + { + if (type == 2 || type == 3) + { + short *sp = (short *)data; + for (int i = 0; i < arraySize; i++) + { + sp[0] = ChunkUtils::swapShort(sp[0]); + sp++; + } + } + if (type > 3 && type < 8) + { + char c; + char *cp = data; + for (int i = 0; i < arraySize; i++) + { + c = cp[0]; + cp[0] = cp[3]; + cp[3] = c; + c = cp[1]; + cp[1] = cp[2]; + cp[2] = c; + cp += 4; + } + } + } +} + +void bFile::safeSwapPtr(char *dst, const char *src) +{ + int ptrFile = mFileDNA->getPointerSize(); + int ptrMem = mMemoryDNA->getPointerSize(); + + if (!src && !dst) + return; + + if (ptrFile == ptrMem) + { + memcpy(dst, src, ptrMem); + } + else if (ptrMem == 4 && ptrFile == 8) + { + btPointerUid *oldPtr = (btPointerUid *)src; + btPointerUid *newPtr = (btPointerUid *)dst; + + if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1]) + { + //Bullet stores the 32bit unique ID in both upper and lower part of 64bit pointers + //so it can be used to distinguish between .blend and .bullet + newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0]; + } + else + { + //deal with pointers the Blender .blend style way, see + //readfile.c in the Blender source tree + long64 longValue = *((long64 *)src); + //endian swap for 64bit pointer otherwise truncation will fail due to trailing zeros + if (mFlags & FD_ENDIAN_SWAP) + SWITCH_LONGINT(longValue); + *((int *)dst) = (int)(longValue >> 3); + } + } + else if (ptrMem == 8 && ptrFile == 4) + { + btPointerUid *oldPtr = (btPointerUid *)src; + btPointerUid *newPtr = (btPointerUid *)dst; + if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1]) + { + newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0]; + newPtr->m_uniqueIds[1] = 0; + } + else + { + *((long64 *)dst) = *((int *)src); + } + } + else + { + printf("%d %d\n", ptrFile, ptrMem); + assert(0 && "Invalid pointer len"); + } +} + +// ----------------------------------------------------- // +void bFile::getMatchingFileDNA(short *dna_addr, const char *lookupName, const char *lookupType, char *strcData, char *data, bool fixupPointers) +{ + // find the matching memory dna data + // to the file being loaded. Fill the + // memory with the file data... + + int len = dna_addr[1]; + dna_addr += 2; + + for (int i = 0; i < len; i++, dna_addr += 2) + { + const char *type = mFileDNA->getType(dna_addr[0]); + const char *name = mFileDNA->getName(dna_addr[1]); + + int eleLen = mFileDNA->getElementSize(dna_addr[0], dna_addr[1]); + + if ((mFlags & FD_BROKEN_DNA) != 0) + { + if ((strcmp(type, "short") == 0) && (strcmp(name, "int") == 0)) + { + eleLen = 0; + } + } + + if (strcmp(lookupName, name) == 0) + { + //int arrayLenold = mFileDNA->getArraySize((char*)name.c_str()); + int arrayLen = mFileDNA->getArraySizeNew(dna_addr[1]); + //assert(arrayLenold == arrayLen); + + if (name[0] == '*') + { + // cast pointers + int ptrFile = mFileDNA->getPointerSize(); + int ptrMem = mMemoryDNA->getPointerSize(); + safeSwapPtr(strcData, data); + + if (fixupPointers) + { + if (arrayLen > 1) + { + //void **sarray = (void**)strcData; + //void **darray = (void**)data; + + char *cpc, *cpo; + cpc = (char *)strcData; + cpo = (char *)data; + + for (int a = 0; a < arrayLen; a++) + { + safeSwapPtr(cpc, cpo); + m_pointerFixupArray.push_back(cpc); + cpc += ptrMem; + cpo += ptrFile; + } + } + else + { + if (name[1] == '*') + m_pointerPtrFixupArray.push_back(strcData); + else + m_pointerFixupArray.push_back(strcData); + } + } + else + { + // printf("skipped %s %s : %x\n",type.c_str(),name.c_str(),strcData); + } + } + + else if (strcmp(type, lookupType) == 0) + memcpy(strcData, data, eleLen); + else + getElement(arrayLen, lookupType, type, data, strcData); + + // -- + return; + } + data += eleLen; + } +} + +// ----------------------------------------------------- // +char *bFile::getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos) +{ + short *old = firstStruct; //mFileDNA->getStruct(old_nr); + int elementLength = old[1]; + old += 2; + + for (int i = 0; i < elementLength; i++, old += 2) + { + char *type = mFileDNA->getType(old[0]); + char *name = mFileDNA->getName(old[1]); + int len = mFileDNA->getElementSize(old[0], old[1]); + + if (strcmp(lookupName, name) == 0) + { + if (strcmp(type, lookupType) == 0) + { + if (foundPos) + *foundPos = old; + return data; + } + return 0; + } + data += len; + } + return 0; +} + +// ----------------------------------------------------- // +void bFile::swapStruct(int dna_nr, char *data, bool ignoreEndianFlag) +{ + if (dna_nr == -1) return; + + short *strc = mFileDNA->getStruct(dna_nr); + //short *firstStrc = strc; + + int elementLen = strc[1]; + strc += 2; + + short first = mFileDNA->getStruct(0)[0]; + + char *buf = data; + for (int i = 0; i < elementLen; i++, strc += 2) + { + char *type = mFileDNA->getType(strc[0]); + char *name = mFileDNA->getName(strc[1]); + + int size = mFileDNA->getElementSize(strc[0], strc[1]); + if (strc[0] >= first && name[0] != '*') + { + int old_nr = mFileDNA->getReverseType(type); + int arrayLen = mFileDNA->getArraySizeNew(strc[1]); + if (arrayLen == 1) + { + swapStruct(old_nr, buf, ignoreEndianFlag); + } + else + { + char *tmpBuf = buf; + for (int i = 0; i < arrayLen; i++) + { + swapStruct(old_nr, tmpBuf, ignoreEndianFlag); + tmpBuf += size / arrayLen; + } + } + } + else + { + //int arrayLenOld = mFileDNA->getArraySize(name); + int arrayLen = mFileDNA->getArraySizeNew(strc[1]); + //assert(arrayLenOld == arrayLen); + swapData(buf, strc[0], arrayLen, ignoreEndianFlag); + } + buf += size; + } +} + +void bFile::resolvePointersMismatch() +{ + // printf("resolvePointersStructMismatch\n"); + + int i; + + for (i = 0; i < m_pointerFixupArray.size(); i++) + { + char *cur = m_pointerFixupArray.at(i); + void **ptrptr = (void **)cur; + void *ptr = *ptrptr; + ptr = findLibPointer(ptr); + if (ptr) + { + //printf("Fixup pointer!\n"); + *(ptrptr) = ptr; + } + else + { + // printf("pointer not found: %x\n",cur); + } + } + + for (i = 0; i < m_pointerPtrFixupArray.size(); i++) + { + char *cur = m_pointerPtrFixupArray.at(i); + void **ptrptr = (void **)cur; + + bChunkInd *block = m_chunkPtrPtrMap.find(*ptrptr); + if (block) + { + int ptrMem = mMemoryDNA->getPointerSize(); + int ptrFile = mFileDNA->getPointerSize(); + + int blockLen = block->len / ptrFile; + + void *onptr = findLibPointer(*ptrptr); + if (onptr) + { + char *newPtr = new char[blockLen * ptrMem]; + addDataBlock(newPtr); + memset(newPtr, 0, blockLen * ptrMem); + + void **onarray = (void **)onptr; + char *oldPtr = (char *)onarray; + + int p = 0; + while (blockLen-- > 0) + { + btPointerUid dp = {{0}}; + safeSwapPtr((char *)dp.m_uniqueIds, oldPtr); + + void **tptr = (void **)(newPtr + p * ptrMem); + *tptr = findLibPointer(dp.m_ptr); + + oldPtr += ptrFile; + ++p; + } + + *ptrptr = newPtr; + } + } + } +} + +///this loop only works fine if the Blender DNA structure of the file matches the headerfiles +void bFile::resolvePointersChunk(const bChunkInd &dataChunk, int verboseMode) +{ + bParse::bDNA *fileDna = mFileDNA ? mFileDNA : mMemoryDNA; + + short int *oldStruct = fileDna->getStruct(dataChunk.dna_nr); + short oldLen = fileDna->getLength(oldStruct[0]); + //char* structType = fileDna->getType(oldStruct[0]); + + char *cur = (char *)findLibPointer(dataChunk.oldPtr); + for (int block = 0; block < dataChunk.nr; block++) + { + resolvePointersStructRecursive(cur, dataChunk.dna_nr, verboseMode, 1); + cur += oldLen; + } +} + +int bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, int verboseMode, int recursion) +{ + bParse::bDNA *fileDna = mFileDNA ? mFileDNA : mMemoryDNA; + + char *memType; + char *memName; + short firstStructType = fileDna->getStruct(0)[0]; + + char *elemPtr = strcPtr; + + short int *oldStruct = fileDna->getStruct(dna_nr); + + int elementLength = oldStruct[1]; + oldStruct += 2; + + int totalSize = 0; + + for (int ele = 0; ele < elementLength; ele++, oldStruct += 2) + { + memType = fileDna->getType(oldStruct[0]); + memName = fileDna->getName(oldStruct[1]); + + int arrayLen = fileDna->getArraySizeNew(oldStruct[1]); + if (memName[0] == '*') + { + if (arrayLen > 1) + { + void **array = (void **)elemPtr; + for (int a = 0; a < arrayLen; a++) + { + if (verboseMode & FD_VERBOSE_EXPORT_XML) + { + for (int i = 0; i < recursion; i++) + { + printf(" "); + } + //skip the * + printf("<%s type=\"pointer\"> ", &memName[1]); + printf("%p ", array[a]); + printf("\n", &memName[1]); + } + + array[a] = findLibPointer(array[a]); + } + } + else + { + void **ptrptr = (void **)elemPtr; + void *ptr = *ptrptr; + if (verboseMode & FD_VERBOSE_EXPORT_XML) + { + for (int i = 0; i < recursion; i++) + { + printf(" "); + } + printf("<%s type=\"pointer\"> ", &memName[1]); + printf("%p ", ptr); + printf("\n", &memName[1]); + } + ptr = findLibPointer(ptr); + + if (ptr) + { + // printf("Fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr); + *(ptrptr) = ptr; + if (memName[1] == '*' && ptrptr && *ptrptr) + { + // This will only work if the given **array is continuous + void **array = (void **)*(ptrptr); + void *np = array[0]; + int n = 0; + while (np) + { + np = findLibPointer(array[n]); + if (np) array[n] = np; + n++; + } + } + } + else + { + // printf("Cannot fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr); + } + } + } + else + { + int revType = fileDna->getReverseType(oldStruct[0]); + if (oldStruct[0] >= firstStructType) //revType != -1 && + { + char cleanName[MAX_STRLEN]; + getCleanName(memName, cleanName); + + int arrayLen = fileDna->getArraySizeNew(oldStruct[1]); + int byteOffset = 0; + + if (verboseMode & FD_VERBOSE_EXPORT_XML) + { + for (int i = 0; i < recursion; i++) + { + printf(" "); + } + + if (arrayLen > 1) + { + printf("<%s type=\"%s\" count=%d>\n", cleanName, memType, arrayLen); + } + else + { + printf("<%s type=\"%s\">\n", cleanName, memType); + } + } + + for (int i = 0; i < arrayLen; i++) + { + byteOffset += resolvePointersStructRecursive(elemPtr + byteOffset, revType, verboseMode, recursion + 1); + } + if (verboseMode & FD_VERBOSE_EXPORT_XML) + { + for (int i = 0; i < recursion; i++) + { + printf(" "); + } + printf("\n", cleanName); + } + } + else + { + //export a simple type + if (verboseMode & FD_VERBOSE_EXPORT_XML) + { + if (arrayLen > MAX_ARRAY_LENGTH) + { + printf("too long\n"); + } + else + { + //printf("%s %s\n",memType,memName); + + bool isIntegerType = (strcmp(memType, "char") == 0) || (strcmp(memType, "int") == 0) || (strcmp(memType, "short") == 0); + + if (isIntegerType) + { + const char *newtype = "int"; + int dbarray[MAX_ARRAY_LENGTH]; + int *dbPtr = 0; + char *tmp = elemPtr; + dbPtr = &dbarray[0]; + if (dbPtr) + { + char cleanName[MAX_STRLEN]; + getCleanName(memName, cleanName); + + int i; + getElement(arrayLen, newtype, memType, tmp, (char *)dbPtr); + for (i = 0; i < recursion; i++) + printf(" "); + if (arrayLen == 1) + printf("<%s type=\"%s\">", cleanName, memType); + else + printf("<%s type=\"%s\" count=%d>", cleanName, memType, arrayLen); + for (i = 0; i < arrayLen; i++) + printf(" %d ", dbPtr[i]); + printf("\n", cleanName); + } + } + else + { + const char *newtype = "double"; + double dbarray[MAX_ARRAY_LENGTH]; + double *dbPtr = 0; + char *tmp = elemPtr; + dbPtr = &dbarray[0]; + if (dbPtr) + { + int i; + getElement(arrayLen, newtype, memType, tmp, (char *)dbPtr); + for (i = 0; i < recursion; i++) + printf(" "); + char cleanName[MAX_STRLEN]; + getCleanName(memName, cleanName); + + if (arrayLen == 1) + { + printf("<%s type=\"%s\">", memName, memType); + } + else + { + printf("<%s type=\"%s\" count=%d>", cleanName, memType, arrayLen); + } + for (i = 0; i < arrayLen; i++) + printf(" %f ", dbPtr[i]); + printf("\n", cleanName); + } + } + } + } + } + } + + int size = fileDna->getElementSize(oldStruct[0], oldStruct[1]); + totalSize += size; + elemPtr += size; + } + + return totalSize; +} + +///Resolve pointers replaces the original pointers in structures, and linked lists by the new in-memory structures +void bFile::resolvePointers(int verboseMode) +{ + bParse::bDNA *fileDna = mFileDNA ? mFileDNA : mMemoryDNA; + + //char *dataPtr = mFileBuffer+mDataStart; + + if (1) //mFlags & (FD_BITS_VARIES | FD_VERSION_VARIES)) + { + resolvePointersMismatch(); + } + + { + if (verboseMode & FD_VERBOSE_EXPORT_XML) + { + printf("\n"); + int numitems = m_chunks.size(); + printf("\n", btGetVersion(), numitems); + } + for (int i = 0; i < m_chunks.size(); i++) + { + const bChunkInd &dataChunk = m_chunks.at(i); + + if (!mFileDNA || fileDna->flagEqual(dataChunk.dna_nr)) + { + //dataChunk.len + short int *oldStruct = fileDna->getStruct(dataChunk.dna_nr); + char *oldType = fileDna->getType(oldStruct[0]); + + if (verboseMode & FD_VERBOSE_EXPORT_XML) + printf(" <%s pointer=%p>\n", oldType, dataChunk.oldPtr); + + resolvePointersChunk(dataChunk, verboseMode); + + if (verboseMode & FD_VERBOSE_EXPORT_XML) + printf(" \n", oldType); + } + else + { + //printf("skipping mStruct\n"); + } + } + if (verboseMode & FD_VERBOSE_EXPORT_XML) + { + printf("\n"); + } + } +} + +// ----------------------------------------------------- // +void *bFile::findLibPointer(void *ptr) +{ + bStructHandle **ptrptr = getLibPointers().find(ptr); + if (ptrptr) + return *ptrptr; + return 0; +} + +void bFile::updateOldPointers() +{ + int i; + + for (i = 0; i < m_chunks.size(); i++) + { + bChunkInd &dataChunk = m_chunks[i]; + dataChunk.oldPtr = findLibPointer(dataChunk.oldPtr); + } +} +void bFile::dumpChunks(bParse::bDNA *dna) +{ + int i; + + for (i = 0; i < m_chunks.size(); i++) + { + bChunkInd &dataChunk = m_chunks[i]; + char *codeptr = (char *)&dataChunk.code; + char codestr[5] = {codeptr[0], codeptr[1], codeptr[2], codeptr[3], 0}; + + short *newStruct = dna->getStruct(dataChunk.dna_nr); + char *typeName = dna->getType(newStruct[0]); + printf("%3d: %s ", i, typeName); + + printf("code=%s ", codestr); + + printf("ptr=%p ", dataChunk.oldPtr); + printf("len=%d ", dataChunk.len); + printf("nr=%d ", dataChunk.nr); + if (dataChunk.nr != 1) + { + printf("not 1\n"); + } + printf("\n"); + } + +#if 0 + IDFinderData ifd; + ifd.success = 0; + ifd.IDname = NULL; + ifd.just_print_it = 1; + for (i=0; im_blocks.size(); ++i) + { + BlendBlock* bb = bf->m_blocks[i]; + printf("tag='%s'\tptr=%p\ttype=%s\t[%4d]", bb->tag, bb,bf->types[bb->type_index].name,bb->m_array_entries_.size()); + block_ID_finder(bb, bf, &ifd); + printf("\n"); + } +#endif +} + +void bFile::writeChunks(FILE *fp, bool fixupPointers) +{ + bParse::bDNA *fileDna = mFileDNA ? mFileDNA : mMemoryDNA; + + for (int i = 0; i < m_chunks.size(); i++) + { + bChunkInd &dataChunk = m_chunks.at(i); + + // Ouch! need to rebuild the struct + short *oldStruct, *curStruct; + char *oldType, *newType; + int curLen, reverseOld; + + oldStruct = fileDna->getStruct(dataChunk.dna_nr); + oldType = fileDna->getType(oldStruct[0]); + //int oldLen = fileDna->getLength(oldStruct[0]); + ///don't try to convert Link block data, just memcpy it. Other data can be converted. + reverseOld = mMemoryDNA->getReverseType(oldType); + + if ((reverseOld != -1)) + { + // make sure it's here + //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!"); + // + curStruct = mMemoryDNA->getStruct(reverseOld); + newType = mMemoryDNA->getType(curStruct[0]); + // make sure it's the same + assert((strcmp(oldType, newType) == 0) && "internal error, struct mismatch!"); + + curLen = mMemoryDNA->getLength(curStruct[0]); + dataChunk.dna_nr = reverseOld; + if (strcmp("Link", oldType) != 0) + { + dataChunk.len = curLen * dataChunk.nr; + } + else + { + // printf("keep length of link = %d\n",dataChunk.len); + } + + //write the structure header + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); + + short int *curStruct1; + curStruct1 = mMemoryDNA->getStruct(dataChunk.dna_nr); + assert(curStruct1 == curStruct); + + char *cur = fixupPointers ? (char *)findLibPointer(dataChunk.oldPtr) : (char *)dataChunk.oldPtr; + + //write the actual contents of the structure(s) + fwrite(cur, dataChunk.len, 1, fp); + } + else + { + printf("serious error, struct mismatch: don't write\n"); + } + } +} + +// ----------------------------------------------------- // +int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags) +{ + bool swap = false; + bool varies = false; + + if (flags & FD_ENDIAN_SWAP) + swap = true; + if (flags & FD_BITS_VARIES) + varies = true; + + if (VOID_IS_8) + { + if (varies) + { + bChunkPtr4 head; + memcpy(&head, dataPtr, sizeof(bChunkPtr4)); + + bChunkPtr8 chunk; + + chunk.code = head.code; + chunk.len = head.len; + chunk.m_uniqueInts[0] = head.m_uniqueInt; + chunk.m_uniqueInts[1] = 0; + chunk.dna_nr = head.dna_nr; + chunk.nr = head.nr; + + if (swap) + { + if ((chunk.code & 0xFFFF) == 0) + chunk.code >>= 16; + + SWITCH_INT(chunk.len); + SWITCH_INT(chunk.dna_nr); + SWITCH_INT(chunk.nr); + } + + memcpy(dataChunk, &chunk, sizeof(bChunkInd)); + } + else + { + bChunkPtr8 c; + memcpy(&c, dataPtr, sizeof(bChunkPtr8)); + + if (swap) + { + if ((c.code & 0xFFFF) == 0) + c.code >>= 16; + + SWITCH_INT(c.len); + SWITCH_INT(c.dna_nr); + SWITCH_INT(c.nr); + } + + memcpy(dataChunk, &c, sizeof(bChunkInd)); + } + } + else + { + if (varies) + { + bChunkPtr8 head; + memcpy(&head, dataPtr, sizeof(bChunkPtr8)); + + bChunkPtr4 chunk; + chunk.code = head.code; + chunk.len = head.len; + + if (head.m_uniqueInts[0] == head.m_uniqueInts[1]) + { + chunk.m_uniqueInt = head.m_uniqueInts[0]; + } + else + { + long64 oldPtr = 0; + memcpy(&oldPtr, &head.m_uniqueInts[0], 8); + if (swap) + SWITCH_LONGINT(oldPtr); + chunk.m_uniqueInt = (int)(oldPtr >> 3); + } + + chunk.dna_nr = head.dna_nr; + chunk.nr = head.nr; + + if (swap) + { + if ((chunk.code & 0xFFFF) == 0) + chunk.code >>= 16; + + SWITCH_INT(chunk.len); + SWITCH_INT(chunk.dna_nr); + SWITCH_INT(chunk.nr); + } + + memcpy(dataChunk, &chunk, sizeof(bChunkInd)); + } + else + { + bChunkPtr4 c; + memcpy(&c, dataPtr, sizeof(bChunkPtr4)); + + if (swap) + { + if ((c.code & 0xFFFF) == 0) + c.code >>= 16; + + SWITCH_INT(c.len); + SWITCH_INT(c.dna_nr); + SWITCH_INT(c.nr); + } + memcpy(dataChunk, &c, sizeof(bChunkInd)); + } + } + + if (dataChunk->len < 0) + return -1; + +#if 0 + print ("----------"); + print (dataChunk->code); + print (dataChunk->len); + print (dataChunk->old); + print (dataChunk->dna_nr); + print (dataChunk->nr); +#endif + return (dataChunk->len + ChunkUtils::getOffset(flags)); +} + +//eof diff --git a/extern/bullet3/Serialize/BulletFileLoader/bFile.h b/extern/bullet3/Serialize/BulletFileLoader/bFile.h new file mode 100644 index 0000000..f6fae97 --- /dev/null +++ b/extern/bullet3/Serialize/BulletFileLoader/bFile.h @@ -0,0 +1,166 @@ +/* +bParse +Copyright (c) 2006-2009 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. 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. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef __BFILE_H__ +#define __BFILE_H__ + +#include "bCommon.h" +#include "bChunk.h" +#include + +namespace bParse +{ +// ----------------------------------------------------- // +enum bFileFlags +{ + FD_INVALID = 0, + FD_OK = 1, + FD_VOID_IS_8 = 2, + FD_ENDIAN_SWAP = 4, + FD_FILE_64 = 8, + FD_BITS_VARIES = 16, + FD_VERSION_VARIES = 32, + FD_DOUBLE_PRECISION = 64, + FD_BROKEN_DNA = 128, + FD_FILEDNA_IS_MEMDNA = 256 +}; + +enum bFileVerboseMode +{ + FD_VERBOSE_EXPORT_XML = 1, + FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS = 2, + FD_VERBOSE_DUMP_CHUNKS = 4, + FD_VERBOSE_DUMP_FILE_INFO = 8, +}; +// ----------------------------------------------------- // +class bFile +{ +protected: + char m_headerString[7]; + + bool mOwnsBuffer; + char* mFileBuffer; + int mFileLen; + int mVersion; + + bPtrMap mLibPointers; + + int mDataStart; + bDNA* mFileDNA; + bDNA* mMemoryDNA; + + btAlignedObjectArray m_pointerFixupArray; + btAlignedObjectArray m_pointerPtrFixupArray; + + btAlignedObjectArray m_chunks; + btHashMap m_chunkPtrPtrMap; + + // + + bPtrMap mDataPointers; + + int mFlags; + + // //////////////////////////////////////////////////////////////////////////// + + // buffer offset util + int getNextBlock(bChunkInd* dataChunk, const char* dataPtr, const int flags); + void safeSwapPtr(char* dst, const char* src); + + virtual void parseHeader(); + + virtual void parseData() = 0; + + void resolvePointersMismatch(); + void resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode); + + int resolvePointersStructRecursive(char* strcPtr, int old_dna, int verboseMode, int recursion); + //void swapPtr(char *dst, char *src); + + void parseStruct(char* strcPtr, char* dtPtr, int old_dna, int new_dna, bool fixupPointers); + void getMatchingFileDNA(short* old, const char* lookupName, const char* lookupType, char* strcData, char* data, bool fixupPointers); + char* getFileElement(short* firstStruct, char* lookupName, char* lookupType, char* data, short** foundPos); + + void swap(char* head, class bChunkInd& ch, bool ignoreEndianFlag); + void swapData(char* data, short type, int arraySize, bool ignoreEndianFlag); + void swapStruct(int dna_nr, char* data, bool ignoreEndianFlag); + void swapLen(char* dataPtr); + void swapDNA(char* ptr); + + char* readStruct(char* head, class bChunkInd& chunk); + char* getAsString(int code); + + virtual void parseInternal(int verboseMode, char* memDna, int memDnaLength); + +public: + bFile(const char* filename, const char headerString[7]); + + //todo: make memoryBuffer const char + //bFile( const char *memoryBuffer, int len); + bFile(char* memoryBuffer, int len, const char headerString[7]); + virtual ~bFile(); + + bDNA* getFileDNA() + { + return mFileDNA; + } + + virtual void addDataBlock(char* dataBlock) = 0; + + int getFlags() const + { + return mFlags; + } + + void setFileDNAisMemoryDNA() + { + mFlags |= FD_FILEDNA_IS_MEMDNA; + } + + bPtrMap& getLibPointers() + { + return mLibPointers; + } + + void* findLibPointer(void* ptr); + + bool ok(); + + virtual void parse(int verboseMode) = 0; + + virtual int write(const char* fileName, bool fixupPointers = false) = 0; + + virtual void writeChunks(FILE* fp, bool fixupPointers); + + virtual void writeDNA(FILE* fp) = 0; + + void updateOldPointers(); + void resolvePointers(int verboseMode); + + void dumpChunks(bDNA* dna); + + virtual void setFileDNA(int verboseMode, char* buffer, int len); + + int getVersion() const + { + return mVersion; + } + //pre-swap the endianness, so that data loaded on a target with different endianness doesn't need to be swapped + void preSwap(); + void writeFile(const char* fileName); +}; +} // namespace bParse + +#endif //__BFILE_H__ diff --git a/extern/bullet3/Serialize/BulletFileLoader/btBulletFile.cpp b/extern/bullet3/Serialize/BulletFileLoader/btBulletFile.cpp new file mode 100644 index 0000000..74f27c4 --- /dev/null +++ b/extern/bullet3/Serialize/BulletFileLoader/btBulletFile.cpp @@ -0,0 +1,425 @@ +/* +bParse +Copyright (c) 2006-2010 Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. 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. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBulletFile.h" +#include "bDefines.h" +#include "bDNA.h" + +#if !defined(__CELLOS_LV2__) && !defined(__MWERKS__) +#include +#endif +#include + +// 32 && 64 bit versions +#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#ifdef _WIN64 +extern char sBulletDNAstr64[]; +extern int sBulletDNAlen64; +#else +extern char sBulletDNAstr[]; +extern int sBulletDNAlen; +#endif //_WIN64 +#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + +extern char sBulletDNAstr64[]; +extern int sBulletDNAlen64; +extern char sBulletDNAstr[]; +extern int sBulletDNAlen; + +#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + +using namespace bParse; + +btBulletFile::btBulletFile() + : bFile("", "BULLET ") +{ + mMemoryDNA = new bDNA(); //this memory gets released in the bFile::~bFile destructor,@todo not consistent with the rule 'who allocates it, has to deallocate it" + + m_DnaCopy = 0; + +#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#ifdef _WIN64 + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16); + memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64); + mMemoryDNA->init(m_DnaCopy, sBulletDNAlen64); +#else //_WIN64 + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16); + memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen); + mMemoryDNA->init(m_DnaCopy, sBulletDNAlen); +#endif //_WIN64 +#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + if (VOID_IS_8) + { + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16); + memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64); + mMemoryDNA->init(m_DnaCopy, sBulletDNAlen64); + } + else + { + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16); + memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen); + mMemoryDNA->init(m_DnaCopy, sBulletDNAlen); + } +#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +} + +btBulletFile::btBulletFile(const char* fileName) + : bFile(fileName, "BULLET ") +{ + m_DnaCopy = 0; +} + +btBulletFile::btBulletFile(char* memoryBuffer, int len) + : bFile(memoryBuffer, len, "BULLET ") +{ + m_DnaCopy = 0; +} + +btBulletFile::~btBulletFile() +{ + if (m_DnaCopy) + btAlignedFree(m_DnaCopy); + + while (m_dataBlocks.size()) + { + char* dataBlock = m_dataBlocks[m_dataBlocks.size() - 1]; + delete[] dataBlock; + m_dataBlocks.pop_back(); + } +} + +// ----------------------------------------------------- // +void btBulletFile::parseData() +{ + // printf ("Building datablocks"); + // printf ("Chunk size = %d",CHUNK_HEADER_LEN); + // printf ("File chunk size = %d",ChunkUtils::getOffset(mFlags)); + + const bool brokenDNA = (mFlags & FD_BROKEN_DNA) != 0; + + //const bool swap = (mFlags&FD_ENDIAN_SWAP)!=0; + + int remain = mFileLen; + + mDataStart = 12; + remain -= 12; + + //invalid/empty file? + if (remain < sizeof(bChunkInd)) + return; + + char* dataPtr = mFileBuffer + mDataStart; + + bChunkInd dataChunk; + dataChunk.code = 0; + + //dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags); + int seek = getNextBlock(&dataChunk, dataPtr, mFlags); + + if (mFlags & FD_ENDIAN_SWAP) + swapLen(dataPtr); + + //dataPtr += ChunkUtils::getOffset(mFlags); + char* dataPtrHead = 0; + + while (dataChunk.code != DNA1) + { + if (!brokenDNA || (dataChunk.code != BT_QUANTIZED_BVH_CODE)) + { + // one behind + if (dataChunk.code == SDNA) break; + //if (dataChunk.code == DNA1) break; + + // same as (BHEAD+DATA dependency) + dataPtrHead = dataPtr + ChunkUtils::getOffset(mFlags); + if (dataChunk.dna_nr >= 0) + { + char* id = readStruct(dataPtrHead, dataChunk); + + // lookup maps + if (id) + { + m_chunkPtrPtrMap.insert(dataChunk.oldPtr, dataChunk); + mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)id); + + m_chunks.push_back(dataChunk); + // block it + //bListBasePtr *listID = mMain->getListBasePtr(dataChunk.code); + //if (listID) + // listID->push_back((bStructHandle*)id); + } + + if (dataChunk.code == BT_CONTACTMANIFOLD_CODE) + { + m_contactManifolds.push_back((bStructHandle*)id); + } + if (dataChunk.code == BT_MULTIBODY_CODE) + { + m_multiBodies.push_back((bStructHandle*)id); + } + + if (dataChunk.code == BT_MB_LINKCOLLIDER_CODE) + { + m_multiBodyLinkColliders.push_back((bStructHandle*)id); + } + + if (dataChunk.code == BT_SOFTBODY_CODE) + { + m_softBodies.push_back((bStructHandle*)id); + } + + if (dataChunk.code == BT_RIGIDBODY_CODE) + { + m_rigidBodies.push_back((bStructHandle*)id); + } + + if (dataChunk.code == BT_DYNAMICSWORLD_CODE) + { + m_dynamicsWorldInfo.push_back((bStructHandle*)id); + } + + if (dataChunk.code == BT_CONSTRAINT_CODE) + { + m_constraints.push_back((bStructHandle*)id); + } + + if (dataChunk.code == BT_QUANTIZED_BVH_CODE) + { + m_bvhs.push_back((bStructHandle*)id); + } + + if (dataChunk.code == BT_TRIANLGE_INFO_MAP) + { + m_triangleInfoMaps.push_back((bStructHandle*)id); + } + + if (dataChunk.code == BT_COLLISIONOBJECT_CODE) + { + m_collisionObjects.push_back((bStructHandle*)id); + } + + if (dataChunk.code == BT_SHAPE_CODE) + { + m_collisionShapes.push_back((bStructHandle*)id); + } + + // if (dataChunk.code == GLOB) + // { + // m_glob = (bStructHandle*) id; + // } + } + else + { + //printf("unknown chunk\n"); + + mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)dataPtrHead); + } + } + else + { + printf("skipping BT_QUANTIZED_BVH_CODE due to broken DNA\n"); + } + + dataPtr += seek; + remain -= seek; + if (remain <= 0) + break; + + seek = getNextBlock(&dataChunk, dataPtr, mFlags); + if (mFlags & FD_ENDIAN_SWAP) + swapLen(dataPtr); + + if (seek < 0) + break; + } +} + +void btBulletFile::addDataBlock(char* dataBlock) +{ + m_dataBlocks.push_back(dataBlock); +} + +void btBulletFile::writeDNA(FILE* fp) +{ + bChunkInd dataChunk; + dataChunk.code = DNA1; + dataChunk.dna_nr = 0; + dataChunk.nr = 1; +#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + if (VOID_IS_8) + { +#ifdef _WIN64 + dataChunk.len = sBulletDNAlen64; + dataChunk.oldPtr = sBulletDNAstr64; + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); + fwrite(sBulletDNAstr64, sBulletDNAlen64, 1, fp); +#else + btAssert(0); +#endif + } + else + { +#ifndef _WIN64 + dataChunk.len = sBulletDNAlen; + dataChunk.oldPtr = sBulletDNAstr; + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); + fwrite(sBulletDNAstr, sBulletDNAlen, 1, fp); +#else //_WIN64 + btAssert(0); +#endif //_WIN64 + } +#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + if (VOID_IS_8) + { + dataChunk.len = sBulletDNAlen64; + dataChunk.oldPtr = sBulletDNAstr64; + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); + fwrite(sBulletDNAstr64, sBulletDNAlen64, 1, fp); + } + else + { + dataChunk.len = sBulletDNAlen; + dataChunk.oldPtr = sBulletDNAstr; + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); + fwrite(sBulletDNAstr, sBulletDNAlen, 1, fp); + } +#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +} + +void btBulletFile::parse(int verboseMode) +{ +#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + if (VOID_IS_8) + { +#ifdef _WIN64 + + if (m_DnaCopy) + delete m_DnaCopy; + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16); + memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64); + parseInternal(verboseMode, (char*)sBulletDNAstr64, sBulletDNAlen64); +#else + btAssert(0); +#endif + } + else + { +#ifndef _WIN64 + + if (m_DnaCopy) + delete m_DnaCopy; + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16); + memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen); + parseInternal(verboseMode, m_DnaCopy, sBulletDNAlen); +#else + btAssert(0); +#endif + } +#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + if (VOID_IS_8) + { + if (m_DnaCopy) + delete m_DnaCopy; + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16); + memset(m_DnaCopy, 0, sBulletDNAlen64); + memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64); + parseInternal(verboseMode, m_DnaCopy, sBulletDNAlen64); + } + else + { + if (m_DnaCopy) + delete m_DnaCopy; + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16); + memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen); + parseInternal(verboseMode, m_DnaCopy, sBulletDNAlen); + } +#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + + //the parsing will convert to cpu endian + mFlags &= ~FD_ENDIAN_SWAP; + + int littleEndian = 1; + littleEndian = ((char*)&littleEndian)[0]; + + mFileBuffer[8] = littleEndian ? 'v' : 'V'; +} + +// experimental +int btBulletFile::write(const char* fileName, bool fixupPointers) +{ + FILE* fp = fopen(fileName, "wb"); + if (fp) + { + char header[SIZEOFBLENDERHEADER]; + memcpy(header, m_headerString, 7); + int endian = 1; + endian = ((char*)&endian)[0]; + + if (endian) + { + header[7] = '_'; + } + else + { + header[7] = '-'; + } + if (VOID_IS_8) + { + header[8] = 'V'; + } + else + { + header[8] = 'v'; + } + + header[9] = '2'; + header[10] = '7'; + header[11] = '5'; + + fwrite(header, SIZEOFBLENDERHEADER, 1, fp); + + writeChunks(fp, fixupPointers); + + writeDNA(fp); + + fclose(fp); + } + else + { + printf("Error: cannot open file %s for writing\n", fileName); + return 0; + } + return 1; +} + +void btBulletFile::addStruct(const char* structType, void* data, int len, void* oldPtr, int code) +{ + bParse::bChunkInd dataChunk; + dataChunk.code = code; + dataChunk.nr = 1; + dataChunk.len = len; + dataChunk.dna_nr = mMemoryDNA->getReverseType(structType); + dataChunk.oldPtr = oldPtr; + + ///Perform structure size validation + short* structInfo = mMemoryDNA->getStruct(dataChunk.dna_nr); + int elemBytes; + elemBytes = mMemoryDNA->getLength(structInfo[0]); + // int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]); + assert(len == elemBytes); + + mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)data); + m_chunks.push_back(dataChunk); +} diff --git a/extern/bullet3/Serialize/BulletFileLoader/btBulletFile.h b/extern/bullet3/Serialize/BulletFileLoader/btBulletFile.h new file mode 100644 index 0000000..d7c1cb7 --- /dev/null +++ b/extern/bullet3/Serialize/BulletFileLoader/btBulletFile.h @@ -0,0 +1,80 @@ +/* +bParse +Copyright (c) 2006-2010 Charlie C & Erwin Coumans http://gamekit.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. 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. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_BULLET_FILE_H +#define BT_BULLET_FILE_H + +#include "bFile.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "bDefines.h" + +#include "LinearMath/btSerializer.h" + +namespace bParse +{ +// ----------------------------------------------------- // +class btBulletFile : public bFile +{ +protected: + char* m_DnaCopy; + +public: + btAlignedObjectArray m_multiBodies; + + btAlignedObjectArray m_multiBodyLinkColliders; + + btAlignedObjectArray m_softBodies; + + btAlignedObjectArray m_rigidBodies; + + btAlignedObjectArray m_collisionObjects; + + btAlignedObjectArray m_collisionShapes; + + btAlignedObjectArray m_constraints; + + btAlignedObjectArray m_bvhs; + + btAlignedObjectArray m_triangleInfoMaps; + + btAlignedObjectArray m_dynamicsWorldInfo; + + btAlignedObjectArray m_contactManifolds; + + btAlignedObjectArray m_dataBlocks; + btBulletFile(); + + btBulletFile(const char* fileName); + + btBulletFile(char* memoryBuffer, int len); + + virtual ~btBulletFile(); + + virtual void addDataBlock(char* dataBlock); + + // experimental + virtual int write(const char* fileName, bool fixupPointers = false); + + virtual void parse(int verboseMode); + + virtual void parseData(); + + virtual void writeDNA(FILE* fp); + + void addStruct(const char* structType, void* data, int len, void* oldPtr, int code); +}; +}; // namespace bParse + +#endif //BT_BULLET_FILE_H diff --git a/extern/bullet3/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp b/extern/bullet3/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp new file mode 100644 index 0000000..b50f056 --- /dev/null +++ b/extern/bullet3/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp @@ -0,0 +1,337 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. 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. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBulletWorldImporter.h" +#include "../BulletFileLoader/btBulletFile.h" + +#include "btBulletDynamicsCommon.h" +#ifndef USE_GIMPACT +#include "BulletCollision/Gimpact/btGImpactShape.h" +#endif + +//#define USE_INTERNAL_EDGE_UTILITY +#ifdef USE_INTERNAL_EDGE_UTILITY +#include "BulletCollision/CollisionDispatch/btInternalEdgeUtility.h" +#endif //USE_INTERNAL_EDGE_UTILITY + +btBulletWorldImporter::btBulletWorldImporter(btDynamicsWorld* world) + : btWorldImporter(world) +{ +} + +btBulletWorldImporter::~btBulletWorldImporter() +{ +} + +bool btBulletWorldImporter::loadFile(const char* fileName, const char* preSwapFilenameOut) +{ + bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName); + + bool result = loadFileFromMemory(bulletFile2); + //now you could save the file in 'native' format using + //bulletFile2->writeFile("native.bullet"); + if (result) + { + if (preSwapFilenameOut) + { + bulletFile2->preSwap(); + bulletFile2->writeFile(preSwapFilenameOut); + } + } + delete bulletFile2; + + return result; +} + +bool btBulletWorldImporter::loadFileFromMemory(char* memoryBuffer, int len) +{ + bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(memoryBuffer, len); + + bool result = loadFileFromMemory(bulletFile2); + + delete bulletFile2; + + return result; +} + +bool btBulletWorldImporter::loadFileFromMemory(bParse::btBulletFile* bulletFile2) +{ + bool ok = (bulletFile2->getFlags() & bParse::FD_OK) != 0; + + if (ok) + bulletFile2->parse(m_verboseMode); + else + return false; + + if (m_verboseMode & bParse::FD_VERBOSE_DUMP_CHUNKS) + { + bulletFile2->dumpChunks(bulletFile2->getFileDNA()); + } + + return convertAllObjects(bulletFile2); +} + +bool btBulletWorldImporter::convertAllObjects(bParse::btBulletFile* bulletFile2) +{ + m_shapeMap.clear(); + m_bodyMap.clear(); + + int i; + + for (i = 0; i < bulletFile2->m_bvhs.size(); i++) + { + btOptimizedBvh* bvh = createOptimizedBvh(); + + if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) + { + btQuantizedBvhDoubleData* bvhData = (btQuantizedBvhDoubleData*)bulletFile2->m_bvhs[i]; + bvh->deSerializeDouble(*bvhData); + } + else + { + btQuantizedBvhFloatData* bvhData = (btQuantizedBvhFloatData*)bulletFile2->m_bvhs[i]; + bvh->deSerializeFloat(*bvhData); + } + m_bvhMap.insert(bulletFile2->m_bvhs[i], bvh); + } + + for (i = 0; i < bulletFile2->m_collisionShapes.size(); i++) + { + btCollisionShapeData* shapeData = (btCollisionShapeData*)bulletFile2->m_collisionShapes[i]; + btCollisionShape* shape = convertCollisionShape(shapeData); + if (shape) + { + // printf("shapeMap.insert(%x,%x)\n",shapeData,shape); + m_shapeMap.insert(shapeData, shape); + } + + if (shape && shapeData->m_name) + { + char* newname = duplicateName(shapeData->m_name); + m_objectNameMap.insert(shape, newname); + m_nameShapeMap.insert(newname, shape); + } + } + + for (int i = 0; i < bulletFile2->m_dynamicsWorldInfo.size(); i++) + { + if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) + { + btDynamicsWorldDoubleData* solverInfoData = (btDynamicsWorldDoubleData*)bulletFile2->m_dynamicsWorldInfo[i]; + btContactSolverInfo solverInfo; + + btVector3 gravity; + gravity.deSerializeDouble(solverInfoData->m_gravity); + + solverInfo.m_tau = btScalar(solverInfoData->m_solverInfo.m_tau); + solverInfo.m_damping = btScalar(solverInfoData->m_solverInfo.m_damping); + solverInfo.m_friction = btScalar(solverInfoData->m_solverInfo.m_friction); + solverInfo.m_timeStep = btScalar(solverInfoData->m_solverInfo.m_timeStep); + + solverInfo.m_restitution = btScalar(solverInfoData->m_solverInfo.m_restitution); + solverInfo.m_maxErrorReduction = btScalar(solverInfoData->m_solverInfo.m_maxErrorReduction); + solverInfo.m_sor = btScalar(solverInfoData->m_solverInfo.m_sor); + solverInfo.m_erp = btScalar(solverInfoData->m_solverInfo.m_erp); + + solverInfo.m_erp2 = btScalar(solverInfoData->m_solverInfo.m_erp2); + solverInfo.m_globalCfm = btScalar(solverInfoData->m_solverInfo.m_globalCfm); + solverInfo.m_splitImpulsePenetrationThreshold = btScalar(solverInfoData->m_solverInfo.m_splitImpulsePenetrationThreshold); + solverInfo.m_splitImpulseTurnErp = btScalar(solverInfoData->m_solverInfo.m_splitImpulseTurnErp); + + solverInfo.m_linearSlop = btScalar(solverInfoData->m_solverInfo.m_linearSlop); + solverInfo.m_warmstartingFactor = btScalar(solverInfoData->m_solverInfo.m_warmstartingFactor); + solverInfo.m_maxGyroscopicForce = btScalar(solverInfoData->m_solverInfo.m_maxGyroscopicForce); + solverInfo.m_singleAxisRollingFrictionThreshold = btScalar(solverInfoData->m_solverInfo.m_singleAxisRollingFrictionThreshold); + + solverInfo.m_numIterations = solverInfoData->m_solverInfo.m_numIterations; + solverInfo.m_solverMode = solverInfoData->m_solverInfo.m_solverMode; + solverInfo.m_restingContactRestitutionThreshold = solverInfoData->m_solverInfo.m_restingContactRestitutionThreshold; + solverInfo.m_minimumSolverBatchSize = solverInfoData->m_solverInfo.m_minimumSolverBatchSize; + + solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse; + + setDynamicsWorldInfo(gravity, solverInfo); + } + else + { + btDynamicsWorldFloatData* solverInfoData = (btDynamicsWorldFloatData*)bulletFile2->m_dynamicsWorldInfo[i]; + btContactSolverInfo solverInfo; + + btVector3 gravity; + gravity.deSerializeFloat(solverInfoData->m_gravity); + + solverInfo.m_tau = solverInfoData->m_solverInfo.m_tau; + solverInfo.m_damping = solverInfoData->m_solverInfo.m_damping; + solverInfo.m_friction = solverInfoData->m_solverInfo.m_friction; + solverInfo.m_timeStep = solverInfoData->m_solverInfo.m_timeStep; + + solverInfo.m_restitution = solverInfoData->m_solverInfo.m_restitution; + solverInfo.m_maxErrorReduction = solverInfoData->m_solverInfo.m_maxErrorReduction; + solverInfo.m_sor = solverInfoData->m_solverInfo.m_sor; + solverInfo.m_erp = solverInfoData->m_solverInfo.m_erp; + + solverInfo.m_erp2 = solverInfoData->m_solverInfo.m_erp2; + solverInfo.m_globalCfm = solverInfoData->m_solverInfo.m_globalCfm; + solverInfo.m_splitImpulsePenetrationThreshold = solverInfoData->m_solverInfo.m_splitImpulsePenetrationThreshold; + solverInfo.m_splitImpulseTurnErp = solverInfoData->m_solverInfo.m_splitImpulseTurnErp; + + solverInfo.m_linearSlop = solverInfoData->m_solverInfo.m_linearSlop; + solverInfo.m_warmstartingFactor = solverInfoData->m_solverInfo.m_warmstartingFactor; + solverInfo.m_maxGyroscopicForce = solverInfoData->m_solverInfo.m_maxGyroscopicForce; + solverInfo.m_singleAxisRollingFrictionThreshold = solverInfoData->m_solverInfo.m_singleAxisRollingFrictionThreshold; + + solverInfo.m_numIterations = solverInfoData->m_solverInfo.m_numIterations; + solverInfo.m_solverMode = solverInfoData->m_solverInfo.m_solverMode; + solverInfo.m_restingContactRestitutionThreshold = solverInfoData->m_solverInfo.m_restingContactRestitutionThreshold; + solverInfo.m_minimumSolverBatchSize = solverInfoData->m_solverInfo.m_minimumSolverBatchSize; + + solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse; + + setDynamicsWorldInfo(gravity, solverInfo); + } + } + + for (i = 0; i < bulletFile2->m_rigidBodies.size(); i++) + { + if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) + { + btRigidBodyDoubleData* colObjData = (btRigidBodyDoubleData*)bulletFile2->m_rigidBodies[i]; + convertRigidBodyDouble(colObjData); + } + else + { + btRigidBodyFloatData* colObjData = (btRigidBodyFloatData*)bulletFile2->m_rigidBodies[i]; + convertRigidBodyFloat(colObjData); + } + } + + for (i = 0; i < bulletFile2->m_collisionObjects.size(); i++) + { + if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) + { + btCollisionObjectDoubleData* colObjData = (btCollisionObjectDoubleData*)bulletFile2->m_collisionObjects[i]; + btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape); + if (shapePtr && *shapePtr) + { + btTransform startTransform; + colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f; + startTransform.deSerializeDouble(colObjData->m_worldTransform); + + btCollisionShape* shape = (btCollisionShape*)*shapePtr; + btCollisionObject* body = createCollisionObject(startTransform, shape, colObjData->m_name); + body->setFriction(btScalar(colObjData->m_friction)); + body->setRestitution(btScalar(colObjData->m_restitution)); + +#ifdef USE_INTERNAL_EDGE_UTILITY + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; + if (trimesh->getTriangleInfoMap()) + { + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + } + } +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData, body); + } + else + { + printf("error: no shape found\n"); + } + } + else + { + btCollisionObjectFloatData* colObjData = (btCollisionObjectFloatData*)bulletFile2->m_collisionObjects[i]; + btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape); + if (shapePtr && *shapePtr) + { + btTransform startTransform; + colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f; + startTransform.deSerializeFloat(colObjData->m_worldTransform); + + btCollisionShape* shape = (btCollisionShape*)*shapePtr; + btCollisionObject* body = createCollisionObject(startTransform, shape, colObjData->m_name); + +#ifdef USE_INTERNAL_EDGE_UTILITY + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; + if (trimesh->getTriangleInfoMap()) + { + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + } + } +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData, body); + } + else + { + printf("error: no shape found\n"); + } + } + } + + for (i = 0; i < bulletFile2->m_constraints.size(); i++) + { + btTypedConstraintData2* constraintData = (btTypedConstraintData2*)bulletFile2->m_constraints[i]; + + btCollisionObject** colAptr = m_bodyMap.find(constraintData->m_rbA); + btCollisionObject** colBptr = m_bodyMap.find(constraintData->m_rbB); + + btRigidBody* rbA = 0; + btRigidBody* rbB = 0; + + if (colAptr) + { + rbA = btRigidBody::upcast(*colAptr); + if (!rbA) + rbA = &getFixedBody(); + } + if (colBptr) + { + rbB = btRigidBody::upcast(*colBptr); + if (!rbB) + rbB = &getFixedBody(); + } + if (!rbA && !rbB) + continue; + + bool isDoublePrecisionData = (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) != 0; + + if (isDoublePrecisionData) + { + if (bulletFile2->getVersion() >= 282) + { + btTypedConstraintDoubleData* dc = (btTypedConstraintDoubleData*)constraintData; + convertConstraintDouble(dc, rbA, rbB, bulletFile2->getVersion()); + } + else + { + //double-precision constraints were messed up until 2.82, try to recover data... + + btTypedConstraintData* oldData = (btTypedConstraintData*)constraintData; + + convertConstraintBackwardsCompatible281(oldData, rbA, rbB, bulletFile2->getVersion()); + } + } + else + { + btTypedConstraintFloatData* dc = (btTypedConstraintFloatData*)constraintData; + convertConstraintFloat(dc, rbA, rbB, bulletFile2->getVersion()); + } + } + + return true; +} diff --git a/extern/bullet3/Serialize/BulletWorldImporter/btBulletWorldImporter.h b/extern/bullet3/Serialize/BulletWorldImporter/btBulletWorldImporter.h new file mode 100644 index 0000000..0a856bc --- /dev/null +++ b/extern/bullet3/Serialize/BulletWorldImporter/btBulletWorldImporter.h @@ -0,0 +1,52 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. 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. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BULLET_WORLD_IMPORTER_H +#define BULLET_WORLD_IMPORTER_H + +#include "btWorldImporter.h" + +class btBulletFile; + +namespace bParse +{ +class btBulletFile; + +}; + +///The btBulletWorldImporter is a starting point to import .bullet files. +///note that not all data is converted yet. You are expected to override or modify this class. +///See Bullet/Demos/SerializeDemo for a derived class that extract btSoftBody objects too. +class btBulletWorldImporter : public btWorldImporter +{ +public: + btBulletWorldImporter(btDynamicsWorld* world = 0); + + virtual ~btBulletWorldImporter(); + + ///if you pass a valid preSwapFilenameOut, it will save a new file with a different endianness + ///this pre-swapped file can be loaded without swapping on a target platform of different endianness + bool loadFile(const char* fileName, const char* preSwapFilenameOut = 0); + + ///the memoryBuffer might be modified (for example if endian swaps are necessary) + bool loadFileFromMemory(char* memoryBuffer, int len); + + bool loadFileFromMemory(bParse::btBulletFile* file); + + //call make sure bulletFile2 has been parsed, either using btBulletFile::parse or btBulletWorldImporter::loadFileFromMemory + virtual bool convertAllObjects(bParse::btBulletFile* file); +}; + +#endif //BULLET_WORLD_IMPORTER_H diff --git a/extern/bullet3/Serialize/BulletWorldImporter/btMultiBodyWorldImporter.cpp b/extern/bullet3/Serialize/BulletWorldImporter/btMultiBodyWorldImporter.cpp new file mode 100644 index 0000000..f18a5d2 --- /dev/null +++ b/extern/bullet3/Serialize/BulletWorldImporter/btMultiBodyWorldImporter.cpp @@ -0,0 +1,571 @@ +#include "btMultiBodyWorldImporter.h" + +#include "LinearMath/btSerializer.h" +#include "../BulletFileLoader/btBulletFile.h" +#include "btBulletWorldImporter.h" +#include "btBulletDynamicsCommon.h" +#include "BulletDynamics/Featherstone/btMultiBody.h" +#include "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h" +#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" + +struct btMultiBodyWorldImporterInternalData +{ + btMultiBodyDynamicsWorld* m_mbDynamicsWorld; + btHashMap m_mbMap; +}; + +btMultiBodyWorldImporter::btMultiBodyWorldImporter(btMultiBodyDynamicsWorld* world) + : btBulletWorldImporter(world) +{ + m_data = new btMultiBodyWorldImporterInternalData; + m_data->m_mbDynamicsWorld = world; +} + +btMultiBodyWorldImporter::~btMultiBodyWorldImporter() +{ + delete m_data; +} + +void btMultiBodyWorldImporter::deleteAllData() +{ + btBulletWorldImporter::deleteAllData(); +} + +static btCollisionObjectDoubleData* getBody0FromContactManifold(btPersistentManifoldDoubleData* manifold) +{ + return (btCollisionObjectDoubleData*)manifold->m_body0; +} +static btCollisionObjectDoubleData* getBody1FromContactManifold(btPersistentManifoldDoubleData* manifold) +{ + return (btCollisionObjectDoubleData*)manifold->m_body1; +} +static btCollisionObjectFloatData* getBody0FromContactManifold(btPersistentManifoldFloatData* manifold) +{ + return (btCollisionObjectFloatData*)manifold->m_body0; +} +static btCollisionObjectFloatData* getBody1FromContactManifold(btPersistentManifoldFloatData* manifold) +{ + return (btCollisionObjectFloatData*)manifold->m_body1; +} + +template +void syncContactManifolds(T** contactManifolds, int numContactManifolds, btMultiBodyWorldImporterInternalData* m_data) +{ + m_data->m_mbDynamicsWorld->updateAabbs(); + m_data->m_mbDynamicsWorld->computeOverlappingPairs(); + btDispatcher* dispatcher = m_data->m_mbDynamicsWorld->getDispatcher(); + + btDispatcherInfo& dispatchInfo = m_data->m_mbDynamicsWorld->getDispatchInfo(); + + if (dispatcher) + { + btOverlappingPairCache* pairCache = m_data->m_mbDynamicsWorld->getBroadphase()->getOverlappingPairCache(); + if (dispatcher) + { + dispatcher->dispatchAllCollisionPairs(pairCache, dispatchInfo, dispatcher); + } + int numExistingManifolds = m_data->m_mbDynamicsWorld->getDispatcher()->getNumManifolds(); + btManifoldArray manifoldArray; + for (int i = 0; i < pairCache->getNumOverlappingPairs(); i++) + { + btBroadphasePair& pair = pairCache->getOverlappingPairArray()[i]; + if (pair.m_algorithm) + { + pair.m_algorithm->getAllContactManifolds(manifoldArray); + //for each existing manifold, search a matching manifoldData and reconstruct + for (int m = 0; m < manifoldArray.size(); m++) + { + btPersistentManifold* existingManifold = manifoldArray[m]; + int uid0 = existingManifold->getBody0()->getBroadphaseHandle()->m_uniqueId; + int uid1 = existingManifold->getBody1()->getBroadphaseHandle()->m_uniqueId; + int matchingManifoldIndex = -1; + for (int q = 0; q < numContactManifolds; q++) + { + if (uid0 == getBody0FromContactManifold(contactManifolds[q])->m_uniqueId && uid1 == getBody1FromContactManifold(contactManifolds[q])->m_uniqueId) + { + matchingManifoldIndex = q; + } + } + if (matchingManifoldIndex >= 0) + { + existingManifold->deSerialize(contactManifolds[matchingManifoldIndex]); + } + else + { + existingManifold->setNumContacts(0); + //printf("Issue: cannot find maching contact manifold (%d, %d), may cause issues in determinism.\n", uid0, uid1); + } + + manifoldArray.clear(); + } + } + } + } +} + +template +void syncMultiBody(T* mbd, btMultiBody* mb, btMultiBodyWorldImporterInternalData* m_data, btAlignedObjectArray& scratchQ, btAlignedObjectArray& scratchM) +{ + bool isFixedBase = mbd->m_baseMass == 0; + bool canSleep = false; + btVector3 baseInertia; + baseInertia.deSerialize(mbd->m_baseInertia); + + btVector3 baseWorldPos; + baseWorldPos.deSerialize(mbd->m_baseWorldPosition); + mb->setBasePos(baseWorldPos); + btQuaternion baseWorldRot; + baseWorldRot.deSerialize(mbd->m_baseWorldOrientation); + mb->setWorldToBaseRot(baseWorldRot.inverse()); + btVector3 baseLinVal; + baseLinVal.deSerialize(mbd->m_baseLinearVelocity); + btVector3 baseAngVel; + baseAngVel.deSerialize(mbd->m_baseAngularVelocity); + mb->setBaseVel(baseLinVal); + mb->setBaseOmega(baseAngVel); + + for (int i = 0; i < mbd->m_numLinks; i++) + { + mb->getLink(i).m_absFrameTotVelocity.m_topVec.deSerialize(mbd->m_links[i].m_absFrameTotVelocityTop); + mb->getLink(i).m_absFrameTotVelocity.m_bottomVec.deSerialize(mbd->m_links[i].m_absFrameTotVelocityBottom); + mb->getLink(i).m_absFrameLocVelocity.m_topVec.deSerialize(mbd->m_links[i].m_absFrameLocVelocityTop); + mb->getLink(i).m_absFrameLocVelocity.m_bottomVec.deSerialize(mbd->m_links[i].m_absFrameLocVelocityBottom); + + switch (mbd->m_links[i].m_jointType) + { + case btMultibodyLink::eFixed: + { + break; + } + case btMultibodyLink::ePrismatic: + { + mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]); + mb->setJointVel(i, mbd->m_links[i].m_jointVel[0]); + break; + } + case btMultibodyLink::eRevolute: + { + mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]); + mb->setJointVel(i, mbd->m_links[i].m_jointVel[0]); + break; + } + case btMultibodyLink::eSpherical: + { + btScalar jointPos[4] = {(btScalar)mbd->m_links[i].m_jointPos[0], (btScalar)mbd->m_links[i].m_jointPos[1], (btScalar)mbd->m_links[i].m_jointPos[2], (btScalar)mbd->m_links[i].m_jointPos[3]}; + btScalar jointVel[3] = {(btScalar)mbd->m_links[i].m_jointVel[0], (btScalar)mbd->m_links[i].m_jointVel[1], (btScalar)mbd->m_links[i].m_jointVel[2]}; + mb->setJointPosMultiDof(i, jointPos); + mb->setJointVelMultiDof(i, jointVel); + + break; + } + case btMultibodyLink::ePlanar: + { + break; + } + default: + { + } + } + } + mb->forwardKinematics(scratchQ, scratchM); + mb->updateCollisionObjectWorldTransforms(scratchQ, scratchM); +} + +template +void convertMultiBody(T* mbd, btMultiBodyWorldImporterInternalData* m_data) +{ + bool isFixedBase = mbd->m_baseMass == 0; + bool canSleep = false; + btVector3 baseInertia; + baseInertia.deSerialize(mbd->m_baseInertia); + btMultiBody* mb = new btMultiBody(mbd->m_numLinks, mbd->m_baseMass, baseInertia, isFixedBase, canSleep); + mb->setHasSelfCollision(false); + + btVector3 baseWorldPos; + baseWorldPos.deSerialize(mbd->m_baseWorldPosition); + + btQuaternion baseWorldOrn; + baseWorldOrn.deSerialize(mbd->m_baseWorldOrientation); + mb->setBasePos(baseWorldPos); + mb->setWorldToBaseRot(baseWorldOrn.inverse()); + + m_data->m_mbMap.insert(mbd, mb); + for (int i = 0; i < mbd->m_numLinks; i++) + { + btVector3 localInertiaDiagonal; + localInertiaDiagonal.deSerialize(mbd->m_links[i].m_linkInertia); + btQuaternion parentRotToThis; + parentRotToThis.deSerialize(mbd->m_links[i].m_zeroRotParentToThis); + btVector3 parentComToThisPivotOffset; + parentComToThisPivotOffset.deSerialize(mbd->m_links[i].m_parentComToThisPivotOffset); + btVector3 thisPivotToThisComOffset; + thisPivotToThisComOffset.deSerialize(mbd->m_links[i].m_thisPivotToThisComOffset); + + switch (mbd->m_links[i].m_jointType) + { + case btMultibodyLink::eFixed: + { + mb->setupFixed(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex, + parentRotToThis, parentComToThisPivotOffset, thisPivotToThisComOffset); + //search for the collider + //mbd->m_links[i].m_linkCollider + break; + } + case btMultibodyLink::ePrismatic: + { + btVector3 jointAxis; + jointAxis.deSerialize(mbd->m_links[i].m_jointAxisBottom[0]); + bool disableParentCollision = true; //todo + mb->setupPrismatic(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex, + parentRotToThis, jointAxis, parentComToThisPivotOffset, thisPivotToThisComOffset, disableParentCollision); + mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]); + mb->finalizeMultiDof(); + mb->setJointVel(i, mbd->m_links[i].m_jointVel[0]); + break; + } + case btMultibodyLink::eRevolute: + { + btVector3 jointAxis; + jointAxis.deSerialize(mbd->m_links[i].m_jointAxisTop[0]); + bool disableParentCollision = true; //todo + mb->setupRevolute(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex, + parentRotToThis, jointAxis, parentComToThisPivotOffset, thisPivotToThisComOffset, disableParentCollision); + mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]); + mb->finalizeMultiDof(); + mb->setJointVel(i, mbd->m_links[i].m_jointVel[0]); + break; + } + case btMultibodyLink::eSpherical: + { + btAssert(0); + bool disableParentCollision = true; //todo + mb->setupSpherical(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex, + parentRotToThis, parentComToThisPivotOffset, thisPivotToThisComOffset, disableParentCollision); + btScalar jointPos[4] = {(btScalar)mbd->m_links[i].m_jointPos[0], (btScalar)mbd->m_links[i].m_jointPos[1], (btScalar)mbd->m_links[i].m_jointPos[2], (btScalar)mbd->m_links[i].m_jointPos[3]}; + btScalar jointVel[3] = {(btScalar)mbd->m_links[i].m_jointVel[0], (btScalar)mbd->m_links[i].m_jointVel[1], (btScalar)mbd->m_links[i].m_jointVel[2]}; + mb->setJointPosMultiDof(i, jointPos); + mb->finalizeMultiDof(); + mb->setJointVelMultiDof(i, jointVel); + + break; + } + case btMultibodyLink::ePlanar: + { + btAssert(0); + break; + } + default: + { + btAssert(0); + } + } + } +} + +bool btMultiBodyWorldImporter::convertAllObjects(bParse::btBulletFile* bulletFile2) +{ + bool result = false; + btAlignedObjectArray scratchQ; + btAlignedObjectArray scratchM; + + if (m_importerFlags & eRESTORE_EXISTING_OBJECTS) + { + //check if the snapshot is valid for the existing world + //equal number of objects, # links etc + if ((bulletFile2->m_multiBodies.size() != m_data->m_mbDynamicsWorld->getNumMultibodies())) + { + printf("btMultiBodyWorldImporter::convertAllObjects error: expected %d multibodies, got %d.\n", m_data->m_mbDynamicsWorld->getNumMultibodies(), bulletFile2->m_multiBodies.size()); + result = false; + return result; + } + result = true; + + //convert all multibodies + if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) + { + //for (int i = 0; i < bulletFile2->m_multiBodies.size(); i++) + for (int i = bulletFile2->m_multiBodies.size() - 1; i >= 0; i--) + { + btMultiBodyDoubleData* mbd = (btMultiBodyDoubleData*)bulletFile2->m_multiBodies[i]; + btMultiBody* mb = m_data->m_mbDynamicsWorld->getMultiBody(i); + if (mbd->m_numLinks != mb->getNumLinks()) + { + printf("btMultiBodyWorldImporter::convertAllObjects error: mismatch in number of links in a body (expected %d, found %d).\n", mbd->m_numLinks, mb->getNumLinks() ); + result = false; + return result; + } else + { + syncMultiBody(mbd, mb, m_data, scratchQ, scratchM); + } + } + + for (int i = bulletFile2->m_rigidBodies.size() - 1; i >= 0; i--) + { + btRigidBodyDoubleData* rbd = (btRigidBodyDoubleData*)bulletFile2->m_rigidBodies[i]; + int foundRb = -1; + int uid = rbd->m_collisionObjectData.m_uniqueId; + for (int i = 0; i < m_data->m_mbDynamicsWorld->getNumCollisionObjects(); i++) + { + if (uid == m_data->m_mbDynamicsWorld->getCollisionObjectArray()[i]->getBroadphaseHandle()->m_uniqueId) + { + foundRb = i; + break; + } + } + if (foundRb >= 0) + { + btRigidBody* rb = btRigidBody::upcast(m_data->m_mbDynamicsWorld->getCollisionObjectArray()[foundRb]); + if (rb) + { + btTransform tr; + tr.deSerializeDouble(rbd->m_collisionObjectData.m_worldTransform); + rb->setWorldTransform(tr); + btVector3 linVel, angVel; + linVel.deSerializeDouble(rbd->m_linearVelocity); + angVel.deSerializeDouble(rbd->m_angularVelocity); + rb->setLinearVelocity(linVel); + rb->setAngularVelocity(angVel); + } + else + { + printf("btMultiBodyWorldImporter::convertAllObjects error: cannot find btRigidBody with bodyUniqueId %d\n", uid); + result = false; + } + } + else + { + printf("Error in btMultiBodyWorldImporter::convertAllObjects: didn't find bodyUniqueId: %d\n", uid); + result = false; + } + } + + //todo: check why body1 pointer is not properly deserialized + for (int i = 0; i < bulletFile2->m_contactManifolds.size(); i++) + { + btPersistentManifoldDoubleData* manifoldData = (btPersistentManifoldDoubleData*)bulletFile2->m_contactManifolds[i]; + { + void* ptr = bulletFile2->findLibPointer(manifoldData->m_body0); + if (ptr) + { + manifoldData->m_body0 = (btCollisionObjectDoubleData*)ptr; + } + } + + { + void* ptr = bulletFile2->findLibPointer(manifoldData->m_body1); + if (ptr) + { + manifoldData->m_body1 = (btCollisionObjectDoubleData*)ptr; + } + } + } + + if (bulletFile2->m_contactManifolds.size()) + { + syncContactManifolds((btPersistentManifoldDoubleData**)&bulletFile2->m_contactManifolds[0], bulletFile2->m_contactManifolds.size(), m_data); + } + } + else + { + //single precision version + //for (int i = 0; i < bulletFile2->m_multiBodies.size(); i++) + for (int i = bulletFile2->m_multiBodies.size() - 1; i >= 0; i--) + { + btMultiBodyFloatData* mbd = (btMultiBodyFloatData*)bulletFile2->m_multiBodies[i]; + btMultiBody* mb = m_data->m_mbDynamicsWorld->getMultiBody(i); + if (mbd->m_numLinks != mb->getNumLinks()) + { + printf("btMultiBodyWorldImporter::convertAllObjects error: mismatch in number of links in a body (expected %d, found %d).\n", mbd->m_numLinks, mb->getNumLinks() ); + result = false; + return result; + } else + { + syncMultiBody(mbd, mb, m_data, scratchQ, scratchM); + } + } + + for (int i = bulletFile2->m_rigidBodies.size() - 1; i >= 0; i--) + { + btRigidBodyFloatData* rbd = (btRigidBodyFloatData*)bulletFile2->m_rigidBodies[i]; + int foundRb = -1; + int uid = rbd->m_collisionObjectData.m_uniqueId; + for (int i = 0; i < m_data->m_mbDynamicsWorld->getNumCollisionObjects(); i++) + { + if (uid == m_data->m_mbDynamicsWorld->getCollisionObjectArray()[i]->getBroadphaseHandle()->m_uniqueId) + { + foundRb = i; + break; + } + } + if (foundRb >= 0) + { + btRigidBody* rb = btRigidBody::upcast(m_data->m_mbDynamicsWorld->getCollisionObjectArray()[foundRb]); + if (rb) + { + btTransform tr; + tr.deSerializeFloat(rbd->m_collisionObjectData.m_worldTransform); + rb->setWorldTransform(tr); + btVector3 linVel, angVel; + linVel.deSerializeFloat(rbd->m_linearVelocity); + angVel.deSerializeFloat(rbd->m_angularVelocity); + rb->setLinearVelocity(linVel); + rb->setAngularVelocity(angVel); + } + else + { + printf("btMultiBodyWorldImporter::convertAllObjects error: cannot find btRigidBody with bodyUniqueId %d\n", uid); + result = false; + } + } + else + { + printf("Error in btMultiBodyWorldImporter::convertAllObjects: didn't find bodyUniqueId: %d\n", uid); + result = false; + } + } + + //todo: check why body1 pointer is not properly deserialized + for (int i = 0; i < bulletFile2->m_contactManifolds.size(); i++) + { + btPersistentManifoldFloatData* manifoldData = (btPersistentManifoldFloatData*)bulletFile2->m_contactManifolds[i]; + { + void* ptr = bulletFile2->findLibPointer(manifoldData->m_body0); + if (ptr) + { + manifoldData->m_body0 = (btCollisionObjectFloatData*)ptr; + } + } + { + void* ptr = bulletFile2->findLibPointer(manifoldData->m_body1); + if (ptr) + { + manifoldData->m_body1 = (btCollisionObjectFloatData*)ptr; + } + } + } + + if (bulletFile2->m_contactManifolds.size()) + { + syncContactManifolds((btPersistentManifoldFloatData**)&bulletFile2->m_contactManifolds[0], bulletFile2->m_contactManifolds.size(), m_data); + } + } + } + else + { + result = btBulletWorldImporter::convertAllObjects(bulletFile2); + + //convert all multibodies + for (int i = 0; i < bulletFile2->m_multiBodies.size(); i++) + { + if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) + { + btMultiBodyDoubleData* mbd = (btMultiBodyDoubleData*)bulletFile2->m_multiBodies[i]; + convertMultiBody(mbd, m_data); + } + else + { + btMultiBodyFloatData* mbd = (btMultiBodyFloatData*)bulletFile2->m_multiBodies[i]; + convertMultiBody(mbd, m_data); + } + } + + //forward kinematics, so that the link world transforms are valid, for collision detection + for (int i = 0; i < m_data->m_mbMap.size(); i++) + { + btMultiBody** ptr = m_data->m_mbMap.getAtIndex(i); + if (ptr) + { + btMultiBody* mb = *ptr; + mb->finalizeMultiDof(); + btVector3 linvel = mb->getBaseVel(); + btVector3 angvel = mb->getBaseOmega(); + mb->forwardKinematics(scratchQ, scratchM); + } + } + + //convert all multibody link colliders + for (int i = 0; i < bulletFile2->m_multiBodyLinkColliders.size(); i++) + { + if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) + { + btMultiBodyLinkColliderDoubleData* mblcd = (btMultiBodyLinkColliderDoubleData*)bulletFile2->m_multiBodyLinkColliders[i]; + + btMultiBody** ptr = m_data->m_mbMap[mblcd->m_multiBody]; + if (ptr) + { + btMultiBody* multiBody = *ptr; + + btCollisionShape** shapePtr = m_shapeMap.find(mblcd->m_colObjData.m_collisionShape); + if (shapePtr && *shapePtr) + { + btTransform startTransform; + mblcd->m_colObjData.m_worldTransform.m_origin.m_floats[3] = 0.f; + startTransform.deSerializeDouble(mblcd->m_colObjData.m_worldTransform); + + btCollisionShape* shape = (btCollisionShape*)*shapePtr; + if (shape) + { + btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(multiBody, mblcd->m_link); + col->setCollisionShape(shape); + //btCollisionObject* body = createCollisionObject(startTransform,shape,mblcd->m_colObjData.m_name); + col->setFriction(btScalar(mblcd->m_colObjData.m_friction)); + col->setRestitution(btScalar(mblcd->m_colObjData.m_restitution)); + //m_bodyMap.insert(colObjData,body); + if (mblcd->m_link == -1) + { + col->setWorldTransform(multiBody->getBaseWorldTransform()); + multiBody->setBaseCollider(col); + } + else + { + col->setWorldTransform(multiBody->getLink(mblcd->m_link).m_cachedWorldTransform); + multiBody->getLink(mblcd->m_link).m_collider = col; + } + int mbLinkIndex = mblcd->m_link; + + bool isDynamic = (mbLinkIndex < 0 && multiBody->hasFixedBase()) ? false : true; + int collisionFilterGroup = isDynamic ? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter); + int collisionFilterMask = isDynamic ? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); + +#if 0 + int colGroup = 0, colMask = 0; + int collisionFlags = mblcd->m_colObjData.m_collisionFlags; + if (collisionFlags & URDF_HAS_COLLISION_GROUP) + { + collisionFilterGroup = colGroup; + } + if (collisionFlags & URDF_HAS_COLLISION_MASK) + { + collisionFilterMask = colMask; + } +#endif + m_data->m_mbDynamicsWorld->addCollisionObject(col, collisionFilterGroup, collisionFilterMask); + } + } + else + { + printf("error: no shape found\n"); + } +#if 0 + //base and fixed? -> static, otherwise flag as dynamic + + world1->addCollisionObject(col, collisionFilterGroup, collisionFilterMask); +#endif + } + } + } + + for (int i = 0; i < m_data->m_mbMap.size(); i++) + { + btMultiBody** ptr = m_data->m_mbMap.getAtIndex(i); + if (ptr) + { + btMultiBody* mb = *ptr; + mb->finalizeMultiDof(); + + m_data->m_mbDynamicsWorld->addMultiBody(mb); + } + } + } + return result; +} \ No newline at end of file diff --git a/extern/bullet3/Serialize/BulletWorldImporter/btMultiBodyWorldImporter.h b/extern/bullet3/Serialize/BulletWorldImporter/btMultiBodyWorldImporter.h new file mode 100644 index 0000000..46dd3ce --- /dev/null +++ b/extern/bullet3/Serialize/BulletWorldImporter/btMultiBodyWorldImporter.h @@ -0,0 +1,19 @@ +#ifndef BT_MULTIBODY_WORLD_IMPORTER_H +#define BT_MULTIBODY_WORLD_IMPORTER_H + +#include "btBulletWorldImporter.h" + +class btMultiBodyWorldImporter : public btBulletWorldImporter +{ + struct btMultiBodyWorldImporterInternalData* m_data; + +public: + btMultiBodyWorldImporter(class btMultiBodyDynamicsWorld* world); + virtual ~btMultiBodyWorldImporter(); + + virtual bool convertAllObjects(bParse::btBulletFile* bulletFile2); + + virtual void deleteAllData(); +}; + +#endif //BT_MULTIBODY_WORLD_IMPORTER_H diff --git a/extern/bullet3/Serialize/BulletWorldImporter/btWorldImporter.cpp b/extern/bullet3/Serialize/BulletWorldImporter/btWorldImporter.cpp new file mode 100644 index 0000000..df41065 --- /dev/null +++ b/extern/bullet3/Serialize/BulletWorldImporter/btWorldImporter.cpp @@ -0,0 +1,2084 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. 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. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btWorldImporter.h" +#include "btBulletDynamicsCommon.h" +#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h" +#ifdef USE_GIMPACT +#include "BulletCollision/Gimpact/btGImpactShape.h" +#endif +btWorldImporter::btWorldImporter(btDynamicsWorld* world) + : m_dynamicsWorld(world), + m_verboseMode(0), + m_importerFlags(0) +{ +} + +btWorldImporter::~btWorldImporter() +{ +} + +void btWorldImporter::deleteAllData() +{ + int i; + for (i = 0; i < m_allocatedConstraints.size(); i++) + { + if (m_dynamicsWorld) + m_dynamicsWorld->removeConstraint(m_allocatedConstraints[i]); + delete m_allocatedConstraints[i]; + } + m_allocatedConstraints.clear(); + + for (i = 0; i < m_allocatedRigidBodies.size(); i++) + { + if (m_dynamicsWorld) + m_dynamicsWorld->removeRigidBody(btRigidBody::upcast(m_allocatedRigidBodies[i])); + delete m_allocatedRigidBodies[i]; + } + + m_allocatedRigidBodies.clear(); + + for (i = 0; i < m_allocatedCollisionShapes.size(); i++) + { + delete m_allocatedCollisionShapes[i]; + } + m_allocatedCollisionShapes.clear(); + + for (i = 0; i < m_allocatedBvhs.size(); i++) + { + delete m_allocatedBvhs[i]; + } + m_allocatedBvhs.clear(); + + for (i = 0; i < m_allocatedTriangleInfoMaps.size(); i++) + { + delete m_allocatedTriangleInfoMaps[i]; + } + m_allocatedTriangleInfoMaps.clear(); + for (i = 0; i < m_allocatedTriangleIndexArrays.size(); i++) + { + delete m_allocatedTriangleIndexArrays[i]; + } + m_allocatedTriangleIndexArrays.clear(); + for (i = 0; i < m_allocatedNames.size(); i++) + { + delete[] m_allocatedNames[i]; + } + m_allocatedNames.clear(); + + for (i = 0; i < m_allocatedbtStridingMeshInterfaceDatas.size(); i++) + { + btStridingMeshInterfaceData* curData = m_allocatedbtStridingMeshInterfaceDatas[i]; + + for (int a = 0; a < curData->m_numMeshParts; a++) + { + btMeshPartData* curPart = &curData->m_meshPartsPtr[a]; + if (curPart->m_vertices3f) + delete[] curPart->m_vertices3f; + + if (curPart->m_vertices3d) + delete[] curPart->m_vertices3d; + + if (curPart->m_indices32) + delete[] curPart->m_indices32; + + if (curPart->m_3indices16) + delete[] curPart->m_3indices16; + + if (curPart->m_indices16) + delete[] curPart->m_indices16; + + if (curPart->m_3indices8) + delete[] curPart->m_3indices8; + } + delete[] curData->m_meshPartsPtr; + delete curData; + } + m_allocatedbtStridingMeshInterfaceDatas.clear(); + + for (i = 0; i < m_indexArrays.size(); i++) + { + btAlignedFree(m_indexArrays[i]); + } + m_indexArrays.clear(); + + for (i = 0; i < m_shortIndexArrays.size(); i++) + { + btAlignedFree(m_shortIndexArrays[i]); + } + m_shortIndexArrays.clear(); + + for (i = 0; i < m_charIndexArrays.size(); i++) + { + btAlignedFree(m_charIndexArrays[i]); + } + m_charIndexArrays.clear(); + + for (i = 0; i < m_floatVertexArrays.size(); i++) + { + btAlignedFree(m_floatVertexArrays[i]); + } + m_floatVertexArrays.clear(); + + for (i = 0; i < m_doubleVertexArrays.size(); i++) + { + btAlignedFree(m_doubleVertexArrays[i]); + } + m_doubleVertexArrays.clear(); +} + +btCollisionShape* btWorldImporter::convertCollisionShape(btCollisionShapeData* shapeData) +{ + btCollisionShape* shape = 0; + + switch (shapeData->m_shapeType) + { + case STATIC_PLANE_PROXYTYPE: + { + btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)shapeData; + btVector3 planeNormal, localScaling; + planeNormal.deSerializeFloat(planeData->m_planeNormal); + localScaling.deSerializeFloat(planeData->m_localScaling); + shape = createPlaneShape(planeNormal, planeData->m_planeConstant); + shape->setLocalScaling(localScaling); + + break; + } + case SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE: + { + btScaledTriangleMeshShapeData* scaledMesh = (btScaledTriangleMeshShapeData*)shapeData; + btCollisionShapeData* colShapeData = (btCollisionShapeData*)&scaledMesh->m_trimeshShapeData; + colShapeData->m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE; + btCollisionShape* childShape = convertCollisionShape(colShapeData); + btBvhTriangleMeshShape* meshShape = (btBvhTriangleMeshShape*)childShape; + btVector3 localScaling; + localScaling.deSerializeFloat(scaledMesh->m_localScaling); + + shape = createScaledTrangleMeshShape(meshShape, localScaling); + break; + } + case GIMPACT_SHAPE_PROXYTYPE: + { +#ifdef USE_GIMPACT + btGImpactMeshShapeData* gimpactData = (btGImpactMeshShapeData*)shapeData; + if (gimpactData->m_gimpactSubType == CONST_GIMPACT_TRIMESH_SHAPE) + { + btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&gimpactData->m_meshInterface); + btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData); + + btGImpactMeshShape* gimpactShape = createGimpactShape(meshInterface); + btVector3 localScaling; + localScaling.deSerializeFloat(gimpactData->m_localScaling); + gimpactShape->setLocalScaling(localScaling); + gimpactShape->setMargin(btScalar(gimpactData->m_collisionMargin)); + gimpactShape->updateBound(); + shape = gimpactShape; + } + else + { + printf("unsupported gimpact sub type\n"); + } +#endif //USE_GIMPACT + break; + } + //The btCapsuleShape* API has issue passing the margin/scaling/halfextents unmodified through the API + //so deal with this + case CAPSULE_SHAPE_PROXYTYPE: + { + btCapsuleShapeData* capData = (btCapsuleShapeData*)shapeData; + + switch (capData->m_upAxis) + { + case 0: + { + shape = createCapsuleShapeX(1, 1); + break; + } + case 1: + { + shape = createCapsuleShapeY(1, 1); + break; + } + case 2: + { + shape = createCapsuleShapeZ(1, 1); + break; + } + default: + { + printf("error: wrong up axis for btCapsuleShape\n"); + } + }; + if (shape) + { + btCapsuleShape* cap = (btCapsuleShape*)shape; + cap->deSerializeFloat(capData); + } + break; + } + case CYLINDER_SHAPE_PROXYTYPE: + case CONE_SHAPE_PROXYTYPE: + case BOX_SHAPE_PROXYTYPE: + case SPHERE_SHAPE_PROXYTYPE: + case MULTI_SPHERE_SHAPE_PROXYTYPE: + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData; + btVector3 implicitShapeDimensions; + implicitShapeDimensions.deSerializeFloat(bsd->m_implicitShapeDimensions); + btVector3 localScaling; + localScaling.deSerializeFloat(bsd->m_localScaling); + btVector3 margin(bsd->m_collisionMargin, bsd->m_collisionMargin, bsd->m_collisionMargin); + switch (shapeData->m_shapeType) + { + case BOX_SHAPE_PROXYTYPE: + { + btBoxShape* box = (btBoxShape*)createBoxShape(implicitShapeDimensions / localScaling + margin); + //box->initializePolyhedralFeatures(); + shape = box; + + break; + } + case SPHERE_SHAPE_PROXYTYPE: + { + shape = createSphereShape(implicitShapeDimensions.getX()); + break; + } + + case CYLINDER_SHAPE_PROXYTYPE: + { + btCylinderShapeData* cylData = (btCylinderShapeData*)shapeData; + btVector3 halfExtents = implicitShapeDimensions + margin; + switch (cylData->m_upAxis) + { + case 0: + { + shape = createCylinderShapeX(halfExtents.getY(), halfExtents.getX()); + break; + } + case 1: + { + shape = createCylinderShapeY(halfExtents.getX(), halfExtents.getY()); + break; + } + case 2: + { + shape = createCylinderShapeZ(halfExtents.getX(), halfExtents.getZ()); + break; + } + default: + { + printf("unknown Cylinder up axis\n"); + } + }; + + break; + } + case CONE_SHAPE_PROXYTYPE: + { + btConeShapeData* conData = (btConeShapeData*)shapeData; + btVector3 halfExtents = implicitShapeDimensions; //+margin; + switch (conData->m_upIndex) + { + case 0: + { + shape = createConeShapeX(halfExtents.getY(), halfExtents.getX()); + break; + } + case 1: + { + shape = createConeShapeY(halfExtents.getX(), halfExtents.getY()); + break; + } + case 2: + { + shape = createConeShapeZ(halfExtents.getX(), halfExtents.getZ()); + break; + } + default: + { + printf("unknown Cone up axis\n"); + } + }; + + break; + } + case MULTI_SPHERE_SHAPE_PROXYTYPE: + { + btMultiSphereShapeData* mss = (btMultiSphereShapeData*)bsd; + int numSpheres = mss->m_localPositionArraySize; + + btAlignedObjectArray tmpPos; + btAlignedObjectArray radii; + radii.resize(numSpheres); + tmpPos.resize(numSpheres); + int i; + for (i = 0; i < numSpheres; i++) + { + tmpPos[i].deSerializeFloat(mss->m_localPositionArrayPtr[i].m_pos); + radii[i] = mss->m_localPositionArrayPtr[i].m_radius; + } + shape = createMultiSphereShape(&tmpPos[0], &radii[0], numSpheres); + break; + } + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + // int sz = sizeof(btConvexHullShapeData); + // int sz2 = sizeof(btConvexInternalShapeData); + // int sz3 = sizeof(btCollisionShapeData); + btConvexHullShapeData* convexData = (btConvexHullShapeData*)bsd; + int numPoints = convexData->m_numUnscaledPoints; + + btAlignedObjectArray tmpPoints; + tmpPoints.resize(numPoints); + int i; + for (i = 0; i < numPoints; i++) + { +#ifdef BT_USE_DOUBLE_PRECISION + if (convexData->m_unscaledPointsDoublePtr) + tmpPoints[i].deSerialize(convexData->m_unscaledPointsDoublePtr[i]); + if (convexData->m_unscaledPointsFloatPtr) + tmpPoints[i].deSerializeFloat(convexData->m_unscaledPointsFloatPtr[i]); +#else + if (convexData->m_unscaledPointsFloatPtr) + tmpPoints[i].deSerialize(convexData->m_unscaledPointsFloatPtr[i]); + if (convexData->m_unscaledPointsDoublePtr) + tmpPoints[i].deSerializeDouble(convexData->m_unscaledPointsDoublePtr[i]); +#endif //BT_USE_DOUBLE_PRECISION + } + btConvexHullShape* hullShape = createConvexHullShape(); + for (i = 0; i < numPoints; i++) + { + hullShape->addPoint(tmpPoints[i]); + } + hullShape->setMargin(bsd->m_collisionMargin); + //hullShape->initializePolyhedralFeatures(); + shape = hullShape; + break; + } + default: + { + printf("error: cannot create shape type (%d)\n", shapeData->m_shapeType); + } + } + + if (shape) + { + shape->setMargin(bsd->m_collisionMargin); + + btVector3 localScaling; + localScaling.deSerializeFloat(bsd->m_localScaling); + shape->setLocalScaling(localScaling); + } + break; + } + case TRIANGLE_MESH_SHAPE_PROXYTYPE: + { + btTriangleMeshShapeData* trimesh = (btTriangleMeshShapeData*)shapeData; + btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&trimesh->m_meshInterface); + btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData); + if (!meshInterface->getNumSubParts()) + { + return 0; + } + + btVector3 scaling; + scaling.deSerializeFloat(trimesh->m_meshInterface.m_scaling); + meshInterface->setScaling(scaling); + + btOptimizedBvh* bvh = 0; +#if 1 + if (trimesh->m_quantizedFloatBvh) + { + btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedFloatBvh); + if (bvhPtr && *bvhPtr) + { + bvh = *bvhPtr; + } + else + { + bvh = createOptimizedBvh(); + bvh->deSerializeFloat(*trimesh->m_quantizedFloatBvh); + } + } + if (trimesh->m_quantizedDoubleBvh) + { + btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedDoubleBvh); + if (bvhPtr && *bvhPtr) + { + bvh = *bvhPtr; + } + else + { + bvh = createOptimizedBvh(); + bvh->deSerializeDouble(*trimesh->m_quantizedDoubleBvh); + } + } +#endif + + btBvhTriangleMeshShape* trimeshShape = createBvhTriangleMeshShape(meshInterface, bvh); + trimeshShape->setMargin(trimesh->m_collisionMargin); + shape = trimeshShape; + + if (trimesh->m_triangleInfoMap) + { + btTriangleInfoMap* map = createTriangleInfoMap(); + map->deSerialize(*trimesh->m_triangleInfoMap); + trimeshShape->setTriangleInfoMap(map); + +#ifdef USE_INTERNAL_EDGE_UTILITY + gContactAddedCallback = btAdjustInternalEdgeContactsCallback; +#endif //USE_INTERNAL_EDGE_UTILITY + } + + //printf("trimesh->m_collisionMargin=%f\n",trimesh->m_collisionMargin); + break; + } + case COMPOUND_SHAPE_PROXYTYPE: + { + btCompoundShapeData* compoundData = (btCompoundShapeData*)shapeData; + btCompoundShape* compoundShape = createCompoundShape(); + + btAlignedObjectArray childShapes; + for (int i = 0; i < compoundData->m_numChildShapes; i++) + { + btCollisionShapeData* cd = compoundData->m_childShapePtr[i].m_childShape; + + btCollisionShape* childShape = convertCollisionShape(cd); + if (childShape) + { + btTransform localTransform; + localTransform.deSerializeFloat(compoundData->m_childShapePtr[i].m_transform); + compoundShape->addChildShape(localTransform, childShape); + } + else + { +#ifdef _DEBUG + printf("error: couldn't create childShape for compoundShape\n"); +#endif + } + } + shape = compoundShape; + + break; + } + case SOFTBODY_SHAPE_PROXYTYPE: + { + return 0; + } + default: + { +#ifdef _DEBUG + printf("unsupported shape type (%d)\n", shapeData->m_shapeType); +#endif + } + } + + return shape; +} + +char* btWorldImporter::duplicateName(const char* name) +{ + if (name) + { + int l = (int)strlen(name); + char* newName = new char[l + 1]; + memcpy(newName, name, l); + newName[l] = 0; + m_allocatedNames.push_back(newName); + return newName; + } + return 0; +} + +void btWorldImporter::convertConstraintBackwardsCompatible281(btTypedConstraintData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion) +{ + btTypedConstraint* constraint = 0; + + switch (constraintData->m_objectType) + { + case POINT2POINT_CONSTRAINT_TYPE: + { + btPoint2PointConstraintDoubleData* p2pData = (btPoint2PointConstraintDoubleData*)constraintData; + if (rbA && rbB) + { + btVector3 pivotInA, pivotInB; + pivotInA.deSerializeDouble(p2pData->m_pivotInA); + pivotInB.deSerializeDouble(p2pData->m_pivotInB); + constraint = createPoint2PointConstraint(*rbA, *rbB, pivotInA, pivotInB); + } + else + { + btVector3 pivotInA; + pivotInA.deSerializeDouble(p2pData->m_pivotInA); + constraint = createPoint2PointConstraint(*rbA, pivotInA); + } + break; + } + case HINGE_CONSTRAINT_TYPE: + { + btHingeConstraint* hinge = 0; + + btHingeConstraintDoubleData* hingeData = (btHingeConstraintDoubleData*)constraintData; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeDouble(hingeData->m_rbAFrame); + rbBFrame.deSerializeDouble(hingeData->m_rbBFrame); + hinge = createHingeConstraint(*rbA, *rbB, rbAFrame, rbBFrame, hingeData->m_useReferenceFrameA != 0); + } + else + { + btTransform rbAFrame; + rbAFrame.deSerializeDouble(hingeData->m_rbAFrame); + hinge = createHingeConstraint(*rbA, rbAFrame, hingeData->m_useReferenceFrameA != 0); + } + if (hingeData->m_enableAngularMotor) + { + hinge->enableAngularMotor(true, (btScalar)hingeData->m_motorTargetVelocity, (btScalar)hingeData->m_maxMotorImpulse); + } + hinge->setAngularOnly(hingeData->m_angularOnly != 0); + hinge->setLimit(btScalar(hingeData->m_lowerLimit), btScalar(hingeData->m_upperLimit), btScalar(hingeData->m_limitSoftness), btScalar(hingeData->m_biasFactor), btScalar(hingeData->m_relaxationFactor)); + + constraint = hinge; + break; + } + case CONETWIST_CONSTRAINT_TYPE: + { + btConeTwistConstraintData* coneData = (btConeTwistConstraintData*)constraintData; + btConeTwistConstraint* coneTwist = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(coneData->m_rbAFrame); + rbBFrame.deSerializeFloat(coneData->m_rbBFrame); + coneTwist = createConeTwistConstraint(*rbA, *rbB, rbAFrame, rbBFrame); + } + else + { + btTransform rbAFrame; + rbAFrame.deSerializeFloat(coneData->m_rbAFrame); + coneTwist = createConeTwistConstraint(*rbA, rbAFrame); + } + coneTwist->setLimit((btScalar)coneData->m_swingSpan1, (btScalar)coneData->m_swingSpan2, (btScalar)coneData->m_twistSpan, (btScalar)coneData->m_limitSoftness, + (btScalar)coneData->m_biasFactor, (btScalar)coneData->m_relaxationFactor); + coneTwist->setDamping((btScalar)coneData->m_damping); + + constraint = coneTwist; + break; + } + + case D6_SPRING_CONSTRAINT_TYPE: + { + btGeneric6DofSpringConstraintData* dofData = (btGeneric6DofSpringConstraintData*)constraintData; + // int sz = sizeof(btGeneric6DofSpringConstraintData); + btGeneric6DofSpringConstraint* dof = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(dofData->m_6dofData.m_rbAFrame); + rbBFrame.deSerializeFloat(dofData->m_6dofData.m_rbBFrame); + dof = createGeneric6DofSpringConstraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_6dofData.m_useLinearReferenceFrameA != 0); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofSpringConstraint: requires rbA && rbB\n"); + } + + if (dof) + { + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; + angLowerLimit.deSerializeFloat(dofData->m_6dofData.m_angularLowerLimit); + angUpperLimit.deSerializeFloat(dofData->m_6dofData.m_angularUpperLimit); + linLowerLimit.deSerializeFloat(dofData->m_6dofData.m_linearLowerLimit); + linUpperlimit.deSerializeFloat(dofData->m_6dofData.m_linearUpperLimit); + + angLowerLimit.setW(0.f); + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + + int i; + if (fileVersion > 280) + { + for (i = 0; i < 6; i++) + { + dof->setStiffness(i, (btScalar)dofData->m_springStiffness[i]); + dof->setEquilibriumPoint(i, (btScalar)dofData->m_equilibriumPoint[i]); + dof->enableSpring(i, dofData->m_springEnabled[i] != 0); + dof->setDamping(i, (btScalar)dofData->m_springDamping[i]); + } + } + } + + constraint = dof; + break; + } + case D6_CONSTRAINT_TYPE: + { + btGeneric6DofConstraintData* dofData = (btGeneric6DofConstraintData*)constraintData; + btGeneric6DofConstraint* dof = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(dofData->m_rbAFrame); + rbBFrame.deSerializeFloat(dofData->m_rbBFrame); + dof = createGeneric6DofConstraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_useLinearReferenceFrameA != 0); + } + else + { + if (rbB) + { + btTransform rbBFrame; + rbBFrame.deSerializeFloat(dofData->m_rbBFrame); + dof = createGeneric6DofConstraint(*rbB, rbBFrame, dofData->m_useLinearReferenceFrameA != 0); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofConstraint: missing rbB\n"); + } + } + + if (dof) + { + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; + angLowerLimit.deSerializeFloat(dofData->m_angularLowerLimit); + angUpperLimit.deSerializeFloat(dofData->m_angularUpperLimit); + linLowerLimit.deSerializeFloat(dofData->m_linearLowerLimit); + linUpperlimit.deSerializeFloat(dofData->m_linearUpperLimit); + + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + } + + constraint = dof; + break; + } + case SLIDER_CONSTRAINT_TYPE: + { + btSliderConstraintData* sliderData = (btSliderConstraintData*)constraintData; + btSliderConstraint* slider = 0; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(sliderData->m_rbAFrame); + rbBFrame.deSerializeFloat(sliderData->m_rbBFrame); + slider = createSliderConstraint(*rbA, *rbB, rbAFrame, rbBFrame, sliderData->m_useLinearReferenceFrameA != 0); + } + else + { + btTransform rbBFrame; + rbBFrame.deSerializeFloat(sliderData->m_rbBFrame); + slider = createSliderConstraint(*rbB, rbBFrame, sliderData->m_useLinearReferenceFrameA != 0); + } + slider->setLowerLinLimit((btScalar)sliderData->m_linearLowerLimit); + slider->setUpperLinLimit((btScalar)sliderData->m_linearUpperLimit); + slider->setLowerAngLimit((btScalar)sliderData->m_angularLowerLimit); + slider->setUpperAngLimit((btScalar)sliderData->m_angularUpperLimit); + slider->setUseFrameOffset(sliderData->m_useOffsetForConstraintFrame != 0); + constraint = slider; + break; + } + + default: + { + printf("unknown constraint type\n"); + } + }; + + if (constraint) + { + constraint->setDbgDrawSize((btScalar)constraintData->m_dbgDrawSize); + ///those fields didn't exist and set to zero for pre-280 versions, so do a check here + if (fileVersion >= 280) + { + constraint->setBreakingImpulseThreshold((btScalar)constraintData->m_breakingImpulseThreshold); + constraint->setEnabled(constraintData->m_isEnabled != 0); + constraint->setOverrideNumSolverIterations(constraintData->m_overrideNumSolverIterations); + } + + if (constraintData->m_name) + { + char* newname = duplicateName(constraintData->m_name); + m_nameConstraintMap.insert(newname, constraint); + m_objectNameMap.insert(constraint, newname); + } + if (m_dynamicsWorld) + m_dynamicsWorld->addConstraint(constraint, constraintData->m_disableCollisionsBetweenLinkedBodies != 0); + } +} + +void btWorldImporter::convertConstraintFloat(btTypedConstraintFloatData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion) +{ + btTypedConstraint* constraint = 0; + + switch (constraintData->m_objectType) + { + case POINT2POINT_CONSTRAINT_TYPE: + { + btPoint2PointConstraintFloatData* p2pData = (btPoint2PointConstraintFloatData*)constraintData; + if (rbA && rbB) + { + btVector3 pivotInA, pivotInB; + pivotInA.deSerializeFloat(p2pData->m_pivotInA); + pivotInB.deSerializeFloat(p2pData->m_pivotInB); + constraint = createPoint2PointConstraint(*rbA, *rbB, pivotInA, pivotInB); + } + else + { + btVector3 pivotInA; + pivotInA.deSerializeFloat(p2pData->m_pivotInA); + constraint = createPoint2PointConstraint(*rbA, pivotInA); + } + break; + } + case HINGE_CONSTRAINT_TYPE: + { + btHingeConstraint* hinge = 0; + btHingeConstraintFloatData* hingeData = (btHingeConstraintFloatData*)constraintData; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(hingeData->m_rbAFrame); + rbBFrame.deSerializeFloat(hingeData->m_rbBFrame); + hinge = createHingeConstraint(*rbA, *rbB, rbAFrame, rbBFrame, hingeData->m_useReferenceFrameA != 0); + } + else + { + btTransform rbAFrame; + rbAFrame.deSerializeFloat(hingeData->m_rbAFrame); + hinge = createHingeConstraint(*rbA, rbAFrame, hingeData->m_useReferenceFrameA != 0); + } + if (hingeData->m_enableAngularMotor) + { + hinge->enableAngularMotor(true, hingeData->m_motorTargetVelocity, hingeData->m_maxMotorImpulse); + } + hinge->setAngularOnly(hingeData->m_angularOnly != 0); + hinge->setLimit(btScalar(hingeData->m_lowerLimit), btScalar(hingeData->m_upperLimit), btScalar(hingeData->m_limitSoftness), btScalar(hingeData->m_biasFactor), btScalar(hingeData->m_relaxationFactor)); + + constraint = hinge; + break; + } + case CONETWIST_CONSTRAINT_TYPE: + { + btConeTwistConstraintData* coneData = (btConeTwistConstraintData*)constraintData; + btConeTwistConstraint* coneTwist = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(coneData->m_rbAFrame); + rbBFrame.deSerializeFloat(coneData->m_rbBFrame); + coneTwist = createConeTwistConstraint(*rbA, *rbB, rbAFrame, rbBFrame); + } + else + { + btTransform rbAFrame; + rbAFrame.deSerializeFloat(coneData->m_rbAFrame); + coneTwist = createConeTwistConstraint(*rbA, rbAFrame); + } + coneTwist->setLimit(coneData->m_swingSpan1, coneData->m_swingSpan2, coneData->m_twistSpan, coneData->m_limitSoftness, coneData->m_biasFactor, coneData->m_relaxationFactor); + coneTwist->setDamping(coneData->m_damping); + + constraint = coneTwist; + break; + } + + case D6_SPRING_CONSTRAINT_TYPE: + { + btGeneric6DofSpringConstraintData* dofData = (btGeneric6DofSpringConstraintData*)constraintData; + // int sz = sizeof(btGeneric6DofSpringConstraintData); + btGeneric6DofSpringConstraint* dof = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(dofData->m_6dofData.m_rbAFrame); + rbBFrame.deSerializeFloat(dofData->m_6dofData.m_rbBFrame); + dof = createGeneric6DofSpringConstraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_6dofData.m_useLinearReferenceFrameA != 0); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofSpringConstraint: requires rbA && rbB\n"); + } + + if (dof) + { + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; + angLowerLimit.deSerializeFloat(dofData->m_6dofData.m_angularLowerLimit); + angUpperLimit.deSerializeFloat(dofData->m_6dofData.m_angularUpperLimit); + linLowerLimit.deSerializeFloat(dofData->m_6dofData.m_linearLowerLimit); + linUpperlimit.deSerializeFloat(dofData->m_6dofData.m_linearUpperLimit); + + angLowerLimit.setW(0.f); + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + + int i; + if (fileVersion > 280) + { + for (i = 0; i < 6; i++) + { + dof->setStiffness(i, dofData->m_springStiffness[i]); + dof->setEquilibriumPoint(i, dofData->m_equilibriumPoint[i]); + dof->enableSpring(i, dofData->m_springEnabled[i] != 0); + dof->setDamping(i, dofData->m_springDamping[i]); + } + } + } + + constraint = dof; + break; + } + case D6_CONSTRAINT_TYPE: + { + btGeneric6DofConstraintData* dofData = (btGeneric6DofConstraintData*)constraintData; + btGeneric6DofConstraint* dof = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(dofData->m_rbAFrame); + rbBFrame.deSerializeFloat(dofData->m_rbBFrame); + dof = createGeneric6DofConstraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_useLinearReferenceFrameA != 0); + } + else + { + if (rbB) + { + btTransform rbBFrame; + rbBFrame.deSerializeFloat(dofData->m_rbBFrame); + dof = createGeneric6DofConstraint(*rbB, rbBFrame, dofData->m_useLinearReferenceFrameA != 0); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofConstraint: missing rbB\n"); + } + } + + if (dof) + { + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; + angLowerLimit.deSerializeFloat(dofData->m_angularLowerLimit); + angUpperLimit.deSerializeFloat(dofData->m_angularUpperLimit); + linLowerLimit.deSerializeFloat(dofData->m_linearLowerLimit); + linUpperlimit.deSerializeFloat(dofData->m_linearUpperLimit); + + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + } + + constraint = dof; + break; + } + case SLIDER_CONSTRAINT_TYPE: + { + btSliderConstraintData* sliderData = (btSliderConstraintData*)constraintData; + btSliderConstraint* slider = 0; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(sliderData->m_rbAFrame); + rbBFrame.deSerializeFloat(sliderData->m_rbBFrame); + slider = createSliderConstraint(*rbA, *rbB, rbAFrame, rbBFrame, sliderData->m_useLinearReferenceFrameA != 0); + } + else + { + btTransform rbBFrame; + rbBFrame.deSerializeFloat(sliderData->m_rbBFrame); + slider = createSliderConstraint(*rbB, rbBFrame, sliderData->m_useLinearReferenceFrameA != 0); + } + slider->setLowerLinLimit(sliderData->m_linearLowerLimit); + slider->setUpperLinLimit(sliderData->m_linearUpperLimit); + slider->setLowerAngLimit(sliderData->m_angularLowerLimit); + slider->setUpperAngLimit(sliderData->m_angularUpperLimit); + slider->setUseFrameOffset(sliderData->m_useOffsetForConstraintFrame != 0); + constraint = slider; + break; + } + case GEAR_CONSTRAINT_TYPE: + { + btGearConstraintFloatData* gearData = (btGearConstraintFloatData*)constraintData; + btGearConstraint* gear = 0; + if (rbA && rbB) + { + btVector3 axisInA, axisInB; + axisInA.deSerializeFloat(gearData->m_axisInA); + axisInB.deSerializeFloat(gearData->m_axisInB); + gear = createGearConstraint(*rbA, *rbB, axisInA, axisInB, gearData->m_ratio); + } + else + { + btAssert(0); + //perhaps a gear against a 'fixed' body, while the 'fixed' body is not serialized? + //btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio=1.f); + } + constraint = gear; + break; + } + case D6_SPRING_2_CONSTRAINT_TYPE: + { + btGeneric6DofSpring2ConstraintData* dofData = (btGeneric6DofSpring2ConstraintData*)constraintData; + + btGeneric6DofSpring2Constraint* dof = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(dofData->m_rbAFrame); + rbBFrame.deSerializeFloat(dofData->m_rbBFrame); + dof = createGeneric6DofSpring2Constraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_rotateOrder); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofSpring2Constraint: requires rbA && rbB\n"); + } + + if (dof) + { + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; + angLowerLimit.deSerializeFloat(dofData->m_angularLowerLimit); + angUpperLimit.deSerializeFloat(dofData->m_angularUpperLimit); + linLowerLimit.deSerializeFloat(dofData->m_linearLowerLimit); + linUpperlimit.deSerializeFloat(dofData->m_linearUpperLimit); + + angLowerLimit.setW(0.f); + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + + int i; + if (fileVersion > 280) + { + //6-dof: 3 linear followed by 3 angular + for (i = 0; i < 3; i++) + { + dof->setStiffness(i, dofData->m_linearSpringStiffness.m_floats[i], dofData->m_linearSpringStiffnessLimited[i] != 0); + dof->setEquilibriumPoint(i, dofData->m_linearEquilibriumPoint.m_floats[i]); + dof->enableSpring(i, dofData->m_linearEnableSpring[i] != 0); + dof->setDamping(i, dofData->m_linearSpringDamping.m_floats[i], (dofData->m_linearSpringDampingLimited[i] != 0)); + } + for (i = 0; i < 3; i++) + { + dof->setStiffness(i + 3, dofData->m_angularSpringStiffness.m_floats[i], (dofData->m_angularSpringStiffnessLimited[i] != 0)); + dof->setEquilibriumPoint(i + 3, dofData->m_angularEquilibriumPoint.m_floats[i]); + dof->enableSpring(i + 3, dofData->m_angularEnableSpring[i] != 0); + dof->setDamping(i + 3, dofData->m_angularSpringDamping.m_floats[i], dofData->m_angularSpringDampingLimited[i]); + } + } + } + + constraint = dof; + break; + } + case FIXED_CONSTRAINT_TYPE: + { + btGeneric6DofSpring2Constraint* dof = 0; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + //compute a shared world frame, and compute frameInA, frameInB relative to this + btTransform sharedFrame; + sharedFrame.setIdentity(); + btVector3 centerPos = btScalar(0.5) * (rbA->getWorldTransform().getOrigin() + + rbB->getWorldTransform().getOrigin()); + sharedFrame.setOrigin(centerPos); + rbAFrame = rbA->getWorldTransform().inverse() * sharedFrame; + rbBFrame = rbB->getWorldTransform().inverse() * sharedFrame; + + dof = createGeneric6DofSpring2Constraint(*rbA, *rbB, rbAFrame, rbBFrame, RO_XYZ); + dof->setLinearUpperLimit(btVector3(0, 0, 0)); + dof->setLinearLowerLimit(btVector3(0, 0, 0)); + dof->setAngularUpperLimit(btVector3(0, 0, 0)); + dof->setAngularLowerLimit(btVector3(0, 0, 0)); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofSpring2Constraint: requires rbA && rbB\n"); + } + + constraint = dof; + break; + } + default: + { + printf("unknown constraint type\n"); + } + }; + + if (constraint) + { + constraint->setDbgDrawSize(constraintData->m_dbgDrawSize); + ///those fields didn't exist and set to zero for pre-280 versions, so do a check here + if (fileVersion >= 280) + { + constraint->setBreakingImpulseThreshold(constraintData->m_breakingImpulseThreshold); + constraint->setEnabled(constraintData->m_isEnabled != 0); + constraint->setOverrideNumSolverIterations(constraintData->m_overrideNumSolverIterations); + } + + if (constraintData->m_name) + { + char* newname = duplicateName(constraintData->m_name); + m_nameConstraintMap.insert(newname, constraint); + m_objectNameMap.insert(constraint, newname); + } + if (m_dynamicsWorld) + m_dynamicsWorld->addConstraint(constraint, constraintData->m_disableCollisionsBetweenLinkedBodies != 0); + } +} + +void btWorldImporter::convertConstraintDouble(btTypedConstraintDoubleData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion) +{ + btTypedConstraint* constraint = 0; + + switch (constraintData->m_objectType) + { + case POINT2POINT_CONSTRAINT_TYPE: + { + btPoint2PointConstraintDoubleData2* p2pData = (btPoint2PointConstraintDoubleData2*)constraintData; + if (rbA && rbB) + { + btVector3 pivotInA, pivotInB; + pivotInA.deSerializeDouble(p2pData->m_pivotInA); + pivotInB.deSerializeDouble(p2pData->m_pivotInB); + constraint = createPoint2PointConstraint(*rbA, *rbB, pivotInA, pivotInB); + } + else + { + btVector3 pivotInA; + pivotInA.deSerializeDouble(p2pData->m_pivotInA); + constraint = createPoint2PointConstraint(*rbA, pivotInA); + } + break; + } + case HINGE_CONSTRAINT_TYPE: + { + btHingeConstraint* hinge = 0; + + btHingeConstraintDoubleData2* hingeData = (btHingeConstraintDoubleData2*)constraintData; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeDouble(hingeData->m_rbAFrame); + rbBFrame.deSerializeDouble(hingeData->m_rbBFrame); + hinge = createHingeConstraint(*rbA, *rbB, rbAFrame, rbBFrame, hingeData->m_useReferenceFrameA != 0); + } + else + { + btTransform rbAFrame; + rbAFrame.deSerializeDouble(hingeData->m_rbAFrame); + hinge = createHingeConstraint(*rbA, rbAFrame, hingeData->m_useReferenceFrameA != 0); + } + if (hingeData->m_enableAngularMotor) + { + hinge->enableAngularMotor(true, (btScalar)hingeData->m_motorTargetVelocity, (btScalar)hingeData->m_maxMotorImpulse); + } + hinge->setAngularOnly(hingeData->m_angularOnly != 0); + hinge->setLimit(btScalar(hingeData->m_lowerLimit), btScalar(hingeData->m_upperLimit), btScalar(hingeData->m_limitSoftness), btScalar(hingeData->m_biasFactor), btScalar(hingeData->m_relaxationFactor)); + + constraint = hinge; + break; + } + case CONETWIST_CONSTRAINT_TYPE: + { + btConeTwistConstraintDoubleData* coneData = (btConeTwistConstraintDoubleData*)constraintData; + btConeTwistConstraint* coneTwist = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeDouble(coneData->m_rbAFrame); + rbBFrame.deSerializeDouble(coneData->m_rbBFrame); + coneTwist = createConeTwistConstraint(*rbA, *rbB, rbAFrame, rbBFrame); + } + else + { + btTransform rbAFrame; + rbAFrame.deSerializeDouble(coneData->m_rbAFrame); + coneTwist = createConeTwistConstraint(*rbA, rbAFrame); + } + coneTwist->setLimit((btScalar)coneData->m_swingSpan1, (btScalar)coneData->m_swingSpan2, (btScalar)coneData->m_twistSpan, (btScalar)coneData->m_limitSoftness, + (btScalar)coneData->m_biasFactor, (btScalar)coneData->m_relaxationFactor); + coneTwist->setDamping((btScalar)coneData->m_damping); + + constraint = coneTwist; + break; + } + + case D6_SPRING_CONSTRAINT_TYPE: + { + btGeneric6DofSpringConstraintDoubleData2* dofData = (btGeneric6DofSpringConstraintDoubleData2*)constraintData; + // int sz = sizeof(btGeneric6DofSpringConstraintData); + btGeneric6DofSpringConstraint* dof = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeDouble(dofData->m_6dofData.m_rbAFrame); + rbBFrame.deSerializeDouble(dofData->m_6dofData.m_rbBFrame); + dof = createGeneric6DofSpringConstraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_6dofData.m_useLinearReferenceFrameA != 0); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofSpringConstraint: requires rbA && rbB\n"); + } + + if (dof) + { + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; + angLowerLimit.deSerializeDouble(dofData->m_6dofData.m_angularLowerLimit); + angUpperLimit.deSerializeDouble(dofData->m_6dofData.m_angularUpperLimit); + linLowerLimit.deSerializeDouble(dofData->m_6dofData.m_linearLowerLimit); + linUpperlimit.deSerializeDouble(dofData->m_6dofData.m_linearUpperLimit); + + angLowerLimit.setW(0.f); + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + + int i; + if (fileVersion > 280) + { + for (i = 0; i < 6; i++) + { + dof->setStiffness(i, (btScalar)dofData->m_springStiffness[i]); + dof->setEquilibriumPoint(i, (btScalar)dofData->m_equilibriumPoint[i]); + dof->enableSpring(i, dofData->m_springEnabled[i] != 0); + dof->setDamping(i, (btScalar)dofData->m_springDamping[i]); + } + } + } + + constraint = dof; + break; + } + case D6_CONSTRAINT_TYPE: + { + btGeneric6DofConstraintDoubleData2* dofData = (btGeneric6DofConstraintDoubleData2*)constraintData; + btGeneric6DofConstraint* dof = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeDouble(dofData->m_rbAFrame); + rbBFrame.deSerializeDouble(dofData->m_rbBFrame); + dof = createGeneric6DofConstraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_useLinearReferenceFrameA != 0); + } + else + { + if (rbB) + { + btTransform rbBFrame; + rbBFrame.deSerializeDouble(dofData->m_rbBFrame); + dof = createGeneric6DofConstraint(*rbB, rbBFrame, dofData->m_useLinearReferenceFrameA != 0); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofConstraint: missing rbB\n"); + } + } + + if (dof) + { + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; + angLowerLimit.deSerializeDouble(dofData->m_angularLowerLimit); + angUpperLimit.deSerializeDouble(dofData->m_angularUpperLimit); + linLowerLimit.deSerializeDouble(dofData->m_linearLowerLimit); + linUpperlimit.deSerializeDouble(dofData->m_linearUpperLimit); + + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + } + + constraint = dof; + break; + } + case SLIDER_CONSTRAINT_TYPE: + { + btSliderConstraintDoubleData* sliderData = (btSliderConstraintDoubleData*)constraintData; + btSliderConstraint* slider = 0; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeDouble(sliderData->m_rbAFrame); + rbBFrame.deSerializeDouble(sliderData->m_rbBFrame); + slider = createSliderConstraint(*rbA, *rbB, rbAFrame, rbBFrame, sliderData->m_useLinearReferenceFrameA != 0); + } + else + { + btTransform rbBFrame; + rbBFrame.deSerializeDouble(sliderData->m_rbBFrame); + slider = createSliderConstraint(*rbB, rbBFrame, sliderData->m_useLinearReferenceFrameA != 0); + } + slider->setLowerLinLimit((btScalar)sliderData->m_linearLowerLimit); + slider->setUpperLinLimit((btScalar)sliderData->m_linearUpperLimit); + slider->setLowerAngLimit((btScalar)sliderData->m_angularLowerLimit); + slider->setUpperAngLimit((btScalar)sliderData->m_angularUpperLimit); + slider->setUseFrameOffset(sliderData->m_useOffsetForConstraintFrame != 0); + constraint = slider; + break; + } + case GEAR_CONSTRAINT_TYPE: + { + btGearConstraintDoubleData* gearData = (btGearConstraintDoubleData*)constraintData; + btGearConstraint* gear = 0; + if (rbA && rbB) + { + btVector3 axisInA, axisInB; + axisInA.deSerializeDouble(gearData->m_axisInA); + axisInB.deSerializeDouble(gearData->m_axisInB); + gear = createGearConstraint(*rbA, *rbB, axisInA, axisInB, gearData->m_ratio); + } + else + { + btAssert(0); + //perhaps a gear against a 'fixed' body, while the 'fixed' body is not serialized? + //btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio=1.f); + } + constraint = gear; + break; + } + + case D6_SPRING_2_CONSTRAINT_TYPE: + { + btGeneric6DofSpring2ConstraintDoubleData2* dofData = (btGeneric6DofSpring2ConstraintDoubleData2*)constraintData; + + btGeneric6DofSpring2Constraint* dof = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeDouble(dofData->m_rbAFrame); + rbBFrame.deSerializeDouble(dofData->m_rbBFrame); + dof = createGeneric6DofSpring2Constraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_rotateOrder); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofSpring2Constraint: requires rbA && rbB\n"); + } + + if (dof) + { + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; + angLowerLimit.deSerializeDouble(dofData->m_angularLowerLimit); + angUpperLimit.deSerializeDouble(dofData->m_angularUpperLimit); + linLowerLimit.deSerializeDouble(dofData->m_linearLowerLimit); + linUpperlimit.deSerializeDouble(dofData->m_linearUpperLimit); + + angLowerLimit.setW(0.f); + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + + int i; + if (fileVersion > 280) + { + //6-dof: 3 linear followed by 3 angular + for (i = 0; i < 3; i++) + { + dof->setStiffness(i, dofData->m_linearSpringStiffness.m_floats[i], dofData->m_linearSpringStiffnessLimited[i]); + dof->setEquilibriumPoint(i, dofData->m_linearEquilibriumPoint.m_floats[i]); + dof->enableSpring(i, dofData->m_linearEnableSpring[i] != 0); + dof->setDamping(i, dofData->m_linearSpringDamping.m_floats[i], (dofData->m_linearSpringDampingLimited[i] != 0)); + } + for (i = 0; i < 3; i++) + { + dof->setStiffness(i + 3, dofData->m_angularSpringStiffness.m_floats[i], (dofData->m_angularSpringStiffnessLimited[i] != 0)); + dof->setEquilibriumPoint(i + 3, dofData->m_angularEquilibriumPoint.m_floats[i]); + dof->enableSpring(i + 3, dofData->m_angularEnableSpring[i] != 0); + dof->setDamping(i + 3, dofData->m_angularSpringDamping.m_floats[i], (dofData->m_angularSpringDampingLimited[i] != 0)); + } + } + } + + constraint = dof; + break; + } + case FIXED_CONSTRAINT_TYPE: + { + btGeneric6DofSpring2Constraint* dof = 0; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + //compute a shared world frame, and compute frameInA, frameInB relative to this + btTransform sharedFrame; + sharedFrame.setIdentity(); + btVector3 centerPos = btScalar(0.5) * (rbA->getWorldTransform().getOrigin() + + rbB->getWorldTransform().getOrigin()); + sharedFrame.setOrigin(centerPos); + rbAFrame = rbA->getWorldTransform().inverse() * sharedFrame; + rbBFrame = rbB->getWorldTransform().inverse() * sharedFrame; + + dof = createGeneric6DofSpring2Constraint(*rbA, *rbB, rbAFrame, rbBFrame, RO_XYZ); + dof->setLinearUpperLimit(btVector3(0, 0, 0)); + dof->setLinearLowerLimit(btVector3(0, 0, 0)); + dof->setAngularUpperLimit(btVector3(0, 0, 0)); + dof->setAngularLowerLimit(btVector3(0, 0, 0)); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofSpring2Constraint: requires rbA && rbB\n"); + } + + constraint = dof; + break; + } + + default: + { + printf("unknown constraint type\n"); + } + }; + + if (constraint) + { + constraint->setDbgDrawSize((btScalar)constraintData->m_dbgDrawSize); + ///those fields didn't exist and set to zero for pre-280 versions, so do a check here + if (fileVersion >= 280) + { + constraint->setBreakingImpulseThreshold((btScalar)constraintData->m_breakingImpulseThreshold); + constraint->setEnabled(constraintData->m_isEnabled != 0); + constraint->setOverrideNumSolverIterations(constraintData->m_overrideNumSolverIterations); + } + + if (constraintData->m_name) + { + char* newname = duplicateName(constraintData->m_name); + m_nameConstraintMap.insert(newname, constraint); + m_objectNameMap.insert(constraint, newname); + } + if (m_dynamicsWorld) + m_dynamicsWorld->addConstraint(constraint, constraintData->m_disableCollisionsBetweenLinkedBodies != 0); + } +} + +btTriangleIndexVertexArray* btWorldImporter::createMeshInterface(btStridingMeshInterfaceData& meshData) +{ + btTriangleIndexVertexArray* meshInterface = createTriangleMeshContainer(); + + for (int i = 0; i < meshData.m_numMeshParts; i++) + { + btIndexedMesh meshPart; + meshPart.m_numTriangles = meshData.m_meshPartsPtr[i].m_numTriangles; + meshPart.m_numVertices = meshData.m_meshPartsPtr[i].m_numVertices; + + if (meshData.m_meshPartsPtr[i].m_indices32) + { + meshPart.m_indexType = PHY_INTEGER; + meshPart.m_triangleIndexStride = 3 * sizeof(int); + int* indexArray = (int*)btAlignedAlloc(sizeof(int) * 3 * meshPart.m_numTriangles, 16); + m_indexArrays.push_back(indexArray); + for (int j = 0; j < 3 * meshPart.m_numTriangles; j++) + { + indexArray[j] = meshData.m_meshPartsPtr[i].m_indices32[j].m_value; + } + meshPart.m_triangleIndexBase = (const unsigned char*)indexArray; + } + else + { + if (meshData.m_meshPartsPtr[i].m_3indices16) + { + meshPart.m_indexType = PHY_SHORT; + meshPart.m_triangleIndexStride = sizeof(short int) * 3; //sizeof(btShortIntIndexTripletData); + + short int* indexArray = (short int*)btAlignedAlloc(sizeof(short int) * 3 * meshPart.m_numTriangles, 16); + m_shortIndexArrays.push_back(indexArray); + + for (int j = 0; j < meshPart.m_numTriangles; j++) + { + indexArray[3 * j] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[0]; + indexArray[3 * j + 1] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[1]; + indexArray[3 * j + 2] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[2]; + } + + meshPart.m_triangleIndexBase = (const unsigned char*)indexArray; + } + if (meshData.m_meshPartsPtr[i].m_indices16) + { + meshPart.m_indexType = PHY_SHORT; + meshPart.m_triangleIndexStride = 3 * sizeof(short int); + short int* indexArray = (short int*)btAlignedAlloc(sizeof(short int) * 3 * meshPart.m_numTriangles, 16); + m_shortIndexArrays.push_back(indexArray); + for (int j = 0; j < 3 * meshPart.m_numTriangles; j++) + { + indexArray[j] = meshData.m_meshPartsPtr[i].m_indices16[j].m_value; + } + + meshPart.m_triangleIndexBase = (const unsigned char*)indexArray; + } + + if (meshData.m_meshPartsPtr[i].m_3indices8) + { + meshPart.m_indexType = PHY_UCHAR; + meshPart.m_triangleIndexStride = sizeof(unsigned char) * 3; + + unsigned char* indexArray = (unsigned char*)btAlignedAlloc(sizeof(unsigned char) * 3 * meshPart.m_numTriangles, 16); + m_charIndexArrays.push_back(indexArray); + + for (int j = 0; j < meshPart.m_numTriangles; j++) + { + indexArray[3 * j] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[0]; + indexArray[3 * j + 1] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[1]; + indexArray[3 * j + 2] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[2]; + } + + meshPart.m_triangleIndexBase = (const unsigned char*)indexArray; + } + } + + if (meshData.m_meshPartsPtr[i].m_vertices3f) + { + meshPart.m_vertexType = PHY_FLOAT; + meshPart.m_vertexStride = sizeof(btVector3FloatData); + btVector3FloatData* vertices = (btVector3FloatData*)btAlignedAlloc(sizeof(btVector3FloatData) * meshPart.m_numVertices, 16); + m_floatVertexArrays.push_back(vertices); + + for (int j = 0; j < meshPart.m_numVertices; j++) + { + vertices[j].m_floats[0] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[0]; + vertices[j].m_floats[1] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[1]; + vertices[j].m_floats[2] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[2]; + vertices[j].m_floats[3] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[3]; + } + meshPart.m_vertexBase = (const unsigned char*)vertices; + } + else + { + meshPart.m_vertexType = PHY_DOUBLE; + meshPart.m_vertexStride = sizeof(btVector3DoubleData); + + btVector3DoubleData* vertices = (btVector3DoubleData*)btAlignedAlloc(sizeof(btVector3DoubleData) * meshPart.m_numVertices, 16); + m_doubleVertexArrays.push_back(vertices); + + for (int j = 0; j < meshPart.m_numVertices; j++) + { + vertices[j].m_floats[0] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[0]; + vertices[j].m_floats[1] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[1]; + vertices[j].m_floats[2] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[2]; + vertices[j].m_floats[3] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[3]; + } + meshPart.m_vertexBase = (const unsigned char*)vertices; + } + + if (meshPart.m_triangleIndexBase && meshPart.m_vertexBase) + { + meshInterface->addIndexedMesh(meshPart, meshPart.m_indexType); + } + } + + return meshInterface; +} + +btStridingMeshInterfaceData* btWorldImporter::createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData) +{ + //create a new btStridingMeshInterfaceData that is an exact copy of shapedata and store it in the WorldImporter + btStridingMeshInterfaceData* newData = new btStridingMeshInterfaceData; + + newData->m_scaling = interfaceData->m_scaling; + newData->m_numMeshParts = interfaceData->m_numMeshParts; + newData->m_meshPartsPtr = new btMeshPartData[newData->m_numMeshParts]; + + for (int i = 0; i < newData->m_numMeshParts; i++) + { + btMeshPartData* curPart = &interfaceData->m_meshPartsPtr[i]; + btMeshPartData* curNewPart = &newData->m_meshPartsPtr[i]; + + curNewPart->m_numTriangles = curPart->m_numTriangles; + curNewPart->m_numVertices = curPart->m_numVertices; + + if (curPart->m_vertices3f) + { + curNewPart->m_vertices3f = new btVector3FloatData[curNewPart->m_numVertices]; + memcpy(curNewPart->m_vertices3f, curPart->m_vertices3f, sizeof(btVector3FloatData) * curNewPart->m_numVertices); + } + else + curNewPart->m_vertices3f = NULL; + + if (curPart->m_vertices3d) + { + curNewPart->m_vertices3d = new btVector3DoubleData[curNewPart->m_numVertices]; + memcpy(curNewPart->m_vertices3d, curPart->m_vertices3d, sizeof(btVector3DoubleData) * curNewPart->m_numVertices); + } + else + curNewPart->m_vertices3d = NULL; + + int numIndices = curNewPart->m_numTriangles * 3; + ///the m_3indices8 was not initialized in some Bullet versions, this can cause crashes at loading time + ///we catch it by only dealing with m_3indices8 if none of the other indices are initialized + bool uninitialized3indices8Workaround = false; + + if (curPart->m_indices32) + { + uninitialized3indices8Workaround = true; + curNewPart->m_indices32 = new btIntIndexData[numIndices]; + memcpy(curNewPart->m_indices32, curPart->m_indices32, sizeof(btIntIndexData) * numIndices); + } + else + curNewPart->m_indices32 = NULL; + + if (curPart->m_3indices16) + { + uninitialized3indices8Workaround = true; + curNewPart->m_3indices16 = new btShortIntIndexTripletData[curNewPart->m_numTriangles]; + memcpy(curNewPart->m_3indices16, curPart->m_3indices16, sizeof(btShortIntIndexTripletData) * curNewPart->m_numTriangles); + } + else + curNewPart->m_3indices16 = NULL; + + if (curPart->m_indices16) + { + uninitialized3indices8Workaround = true; + curNewPart->m_indices16 = new btShortIntIndexData[numIndices]; + memcpy(curNewPart->m_indices16, curPart->m_indices16, sizeof(btShortIntIndexData) * numIndices); + } + else + curNewPart->m_indices16 = NULL; + + if (!uninitialized3indices8Workaround && curPart->m_3indices8) + { + curNewPart->m_3indices8 = new btCharIndexTripletData[curNewPart->m_numTriangles]; + memcpy(curNewPart->m_3indices8, curPart->m_3indices8, sizeof(btCharIndexTripletData) * curNewPart->m_numTriangles); + } + else + curNewPart->m_3indices8 = NULL; + } + + m_allocatedbtStridingMeshInterfaceDatas.push_back(newData); + + return (newData); +} + +#ifdef USE_INTERNAL_EDGE_UTILITY +extern ContactAddedCallback gContactAddedCallback; + +static bool btAdjustInternalEdgeContactsCallback(btManifoldPoint& cp, const btCollisionObject* colObj0, int partId0, int index0, const btCollisionObject* colObj1, int partId1, int index1) +{ + btAdjustInternalEdgeContacts(cp, colObj1, colObj0, partId1, index1); + //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE); + //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED); + return true; +} +#endif //USE_INTERNAL_EDGE_UTILITY + +btCollisionObject* btWorldImporter::createCollisionObject(const btTransform& startTransform, btCollisionShape* shape, const char* bodyName) +{ + return createRigidBody(false, 0, startTransform, shape, bodyName); +} + +void btWorldImporter::setDynamicsWorldInfo(const btVector3& gravity, const btContactSolverInfo& solverInfo) +{ + if (m_dynamicsWorld) + { + m_dynamicsWorld->setGravity(gravity); + m_dynamicsWorld->getSolverInfo() = solverInfo; + } +} + +btRigidBody* btWorldImporter::createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform, btCollisionShape* shape, const char* bodyName) +{ + btVector3 localInertia; + localInertia.setZero(); + + if (mass) + shape->calculateLocalInertia(mass, localInertia); + + btRigidBody* body = new btRigidBody(mass, 0, shape, localInertia); + body->setWorldTransform(startTransform); + + if (m_dynamicsWorld) + m_dynamicsWorld->addRigidBody(body); + + if (bodyName) + { + char* newname = duplicateName(bodyName); + m_objectNameMap.insert(body, newname); + m_nameBodyMap.insert(newname, body); + } + m_allocatedRigidBodies.push_back(body); + return body; +} + +btCollisionShape* btWorldImporter::createPlaneShape(const btVector3& planeNormal, btScalar planeConstant) +{ + btStaticPlaneShape* shape = new btStaticPlaneShape(planeNormal, planeConstant); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} +btCollisionShape* btWorldImporter::createBoxShape(const btVector3& halfExtents) +{ + btBoxShape* shape = new btBoxShape(halfExtents); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} +btCollisionShape* btWorldImporter::createSphereShape(btScalar radius) +{ + btSphereShape* shape = new btSphereShape(radius); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btWorldImporter::createCapsuleShapeX(btScalar radius, btScalar height) +{ + btCapsuleShapeX* shape = new btCapsuleShapeX(radius, height); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btWorldImporter::createCapsuleShapeY(btScalar radius, btScalar height) +{ + btCapsuleShape* shape = new btCapsuleShape(radius, height); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btWorldImporter::createCapsuleShapeZ(btScalar radius, btScalar height) +{ + btCapsuleShapeZ* shape = new btCapsuleShapeZ(radius, height); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btWorldImporter::createCylinderShapeX(btScalar radius, btScalar height) +{ + btCylinderShapeX* shape = new btCylinderShapeX(btVector3(height, radius, radius)); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btWorldImporter::createCylinderShapeY(btScalar radius, btScalar height) +{ + btCylinderShape* shape = new btCylinderShape(btVector3(radius, height, radius)); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btWorldImporter::createCylinderShapeZ(btScalar radius, btScalar height) +{ + btCylinderShapeZ* shape = new btCylinderShapeZ(btVector3(radius, radius, height)); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btWorldImporter::createConeShapeX(btScalar radius, btScalar height) +{ + btConeShapeX* shape = new btConeShapeX(radius, height); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btWorldImporter::createConeShapeY(btScalar radius, btScalar height) +{ + btConeShape* shape = new btConeShape(radius, height); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCollisionShape* btWorldImporter::createConeShapeZ(btScalar radius, btScalar height) +{ + btConeShapeZ* shape = new btConeShapeZ(radius, height); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btTriangleIndexVertexArray* btWorldImporter::createTriangleMeshContainer() +{ + btTriangleIndexVertexArray* in = new btTriangleIndexVertexArray(); + m_allocatedTriangleIndexArrays.push_back(in); + return in; +} + +btOptimizedBvh* btWorldImporter::createOptimizedBvh() +{ + btOptimizedBvh* bvh = new btOptimizedBvh(); + m_allocatedBvhs.push_back(bvh); + return bvh; +} + +btTriangleInfoMap* btWorldImporter::createTriangleInfoMap() +{ + btTriangleInfoMap* tim = new btTriangleInfoMap(); + m_allocatedTriangleInfoMaps.push_back(tim); + return tim; +} + +btBvhTriangleMeshShape* btWorldImporter::createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh) +{ + if (bvh) + { + btBvhTriangleMeshShape* bvhTriMesh = new btBvhTriangleMeshShape(trimesh, bvh->isQuantized(), false); + bvhTriMesh->setOptimizedBvh(bvh); + m_allocatedCollisionShapes.push_back(bvhTriMesh); + return bvhTriMesh; + } + + btBvhTriangleMeshShape* ts = new btBvhTriangleMeshShape(trimesh, true); + m_allocatedCollisionShapes.push_back(ts); + return ts; +} +btCollisionShape* btWorldImporter::createConvexTriangleMeshShape(btStridingMeshInterface* trimesh) +{ + return 0; +} +btGImpactMeshShape* btWorldImporter::createGimpactShape(btStridingMeshInterface* trimesh) +{ +#ifdef USE_GIMPACT + btGImpactMeshShape* shape = new btGImpactMeshShape(trimesh); + m_allocatedCollisionShapes.push_back(shape); + return shape; +#else + return 0; +#endif +} +btConvexHullShape* btWorldImporter::createConvexHullShape() +{ + btConvexHullShape* shape = new btConvexHullShape(); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btCompoundShape* btWorldImporter::createCompoundShape() +{ + btCompoundShape* shape = new btCompoundShape(); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btScaledBvhTriangleMeshShape* btWorldImporter::createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape, const btVector3& localScaling) +{ + btScaledBvhTriangleMeshShape* shape = new btScaledBvhTriangleMeshShape(meshShape, localScaling); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btMultiSphereShape* btWorldImporter::createMultiSphereShape(const btVector3* positions, const btScalar* radi, int numSpheres) +{ + btMultiSphereShape* shape = new btMultiSphereShape(positions, radi, numSpheres); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +class btHeightfieldTerrainShape* btWorldImporter::createHeightfieldShape(int heightStickWidth, int heightStickLength, + const void* heightfieldData, btScalar heightScale, + btScalar minHeight, btScalar maxHeight, + int upAxis, int heightDataType, + bool flipQuadEdges) +{ + + btHeightfieldTerrainShape* shape = new btHeightfieldTerrainShape(heightStickWidth, heightStickLength, + heightfieldData, heightScale, minHeight, maxHeight, upAxis, PHY_ScalarType(heightDataType), flipQuadEdges); + m_allocatedCollisionShapes.push_back(shape); + return shape; +} + +btRigidBody& btWorldImporter::getFixedBody() +{ + static btRigidBody s_fixed(0, 0, 0); + s_fixed.setMassProps(btScalar(0.), btVector3(btScalar(0.), btScalar(0.), btScalar(0.))); + return s_fixed; +} + +btPoint2PointConstraint* btWorldImporter::createPoint2PointConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& pivotInA, const btVector3& pivotInB) +{ + btPoint2PointConstraint* p2p = new btPoint2PointConstraint(rbA, rbB, pivotInA, pivotInB); + m_allocatedConstraints.push_back(p2p); + return p2p; +} + +btPoint2PointConstraint* btWorldImporter::createPoint2PointConstraint(btRigidBody& rbA, const btVector3& pivotInA) +{ + btPoint2PointConstraint* p2p = new btPoint2PointConstraint(rbA, pivotInA); + m_allocatedConstraints.push_back(p2p); + return p2p; +} + +btHingeConstraint* btWorldImporter::createHingeConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA) +{ + btHingeConstraint* hinge = new btHingeConstraint(rbA, rbB, rbAFrame, rbBFrame, useReferenceFrameA); + m_allocatedConstraints.push_back(hinge); + return hinge; +} + +btHingeConstraint* btWorldImporter::createHingeConstraint(btRigidBody& rbA, const btTransform& rbAFrame, bool useReferenceFrameA) +{ + btHingeConstraint* hinge = new btHingeConstraint(rbA, rbAFrame, useReferenceFrameA); + m_allocatedConstraints.push_back(hinge); + return hinge; +} + +btConeTwistConstraint* btWorldImporter::createConeTwistConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame) +{ + btConeTwistConstraint* cone = new btConeTwistConstraint(rbA, rbB, rbAFrame, rbBFrame); + m_allocatedConstraints.push_back(cone); + return cone; +} + +btConeTwistConstraint* btWorldImporter::createConeTwistConstraint(btRigidBody& rbA, const btTransform& rbAFrame) +{ + btConeTwistConstraint* cone = new btConeTwistConstraint(rbA, rbAFrame); + m_allocatedConstraints.push_back(cone); + return cone; +} + +btGeneric6DofConstraint* btWorldImporter::createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) +{ + btGeneric6DofConstraint* dof = new btGeneric6DofConstraint(rbA, rbB, frameInA, frameInB, useLinearReferenceFrameA); + m_allocatedConstraints.push_back(dof); + return dof; +} + +btGeneric6DofConstraint* btWorldImporter::createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB) +{ + btGeneric6DofConstraint* dof = new btGeneric6DofConstraint(rbB, frameInB, useLinearReferenceFrameB); + m_allocatedConstraints.push_back(dof); + return dof; +} + +btGeneric6DofSpring2Constraint* btWorldImporter::createGeneric6DofSpring2Constraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, int rotateOrder) +{ + btGeneric6DofSpring2Constraint* dof = new btGeneric6DofSpring2Constraint(rbA, rbB, frameInA, frameInB, (RotateOrder)rotateOrder); + m_allocatedConstraints.push_back(dof); + return dof; +} + +btGeneric6DofSpringConstraint* btWorldImporter::createGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) +{ + btGeneric6DofSpringConstraint* dof = new btGeneric6DofSpringConstraint(rbA, rbB, frameInA, frameInB, useLinearReferenceFrameA); + m_allocatedConstraints.push_back(dof); + return dof; +} + +btSliderConstraint* btWorldImporter::createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) +{ + btSliderConstraint* slider = new btSliderConstraint(rbA, rbB, frameInA, frameInB, useLinearReferenceFrameA); + m_allocatedConstraints.push_back(slider); + return slider; +} + +btSliderConstraint* btWorldImporter::createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA) +{ + btSliderConstraint* slider = new btSliderConstraint(rbB, frameInB, useLinearReferenceFrameA); + m_allocatedConstraints.push_back(slider); + return slider; +} + +btGearConstraint* btWorldImporter::createGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA, const btVector3& axisInB, btScalar ratio) +{ + btGearConstraint* gear = new btGearConstraint(rbA, rbB, axisInA, axisInB, ratio); + m_allocatedConstraints.push_back(gear); + return gear; +} + +// query for data +int btWorldImporter::getNumCollisionShapes() const +{ + return m_allocatedCollisionShapes.size(); +} + +btCollisionShape* btWorldImporter::getCollisionShapeByIndex(int index) +{ + return m_allocatedCollisionShapes[index]; +} + +btCollisionShape* btWorldImporter::getCollisionShapeByName(const char* name) +{ + btCollisionShape** shapePtr = m_nameShapeMap.find(name); + if (shapePtr && *shapePtr) + { + return *shapePtr; + } + return 0; +} + +btRigidBody* btWorldImporter::getRigidBodyByName(const char* name) +{ + btRigidBody** bodyPtr = m_nameBodyMap.find(name); + if (bodyPtr && *bodyPtr) + { + return *bodyPtr; + } + return 0; +} + +btTypedConstraint* btWorldImporter::getConstraintByName(const char* name) +{ + btTypedConstraint** constraintPtr = m_nameConstraintMap.find(name); + if (constraintPtr && *constraintPtr) + { + return *constraintPtr; + } + return 0; +} + +const char* btWorldImporter::getNameForPointer(const void* ptr) const +{ + const char* const* namePtr = m_objectNameMap.find(ptr); + if (namePtr && *namePtr) + return *namePtr; + return 0; +} + +int btWorldImporter::getNumRigidBodies() const +{ + return m_allocatedRigidBodies.size(); +} + +btCollisionObject* btWorldImporter::getRigidBodyByIndex(int index) const +{ + return m_allocatedRigidBodies[index]; +} +int btWorldImporter::getNumConstraints() const +{ + return m_allocatedConstraints.size(); +} + +btTypedConstraint* btWorldImporter::getConstraintByIndex(int index) const +{ + return m_allocatedConstraints[index]; +} + +int btWorldImporter::getNumBvhs() const +{ + return m_allocatedBvhs.size(); +} +btOptimizedBvh* btWorldImporter::getBvhByIndex(int index) const +{ + return m_allocatedBvhs[index]; +} + +int btWorldImporter::getNumTriangleInfoMaps() const +{ + return m_allocatedTriangleInfoMaps.size(); +} + +btTriangleInfoMap* btWorldImporter::getTriangleInfoMapByIndex(int index) const +{ + return m_allocatedTriangleInfoMaps[index]; +} + +void btWorldImporter::convertRigidBodyFloat(btRigidBodyFloatData* colObjData) +{ + btScalar mass = btScalar(colObjData->m_inverseMass ? 1.f / colObjData->m_inverseMass : 0.f); + btVector3 localInertia; + localInertia.setZero(); + btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionObjectData.m_collisionShape); + if (shapePtr && *shapePtr) + { + btTransform startTransform; + colObjData->m_collisionObjectData.m_worldTransform.m_origin.m_floats[3] = 0.f; + startTransform.deSerializeFloat(colObjData->m_collisionObjectData.m_worldTransform); + + // startTransform.setBasis(btMatrix3x3::getIdentity()); + btCollisionShape* shape = (btCollisionShape*)*shapePtr; + if (shape->isNonMoving()) + { + mass = 0.f; + } + if (mass) + { + shape->calculateLocalInertia(mass, localInertia); + } + bool isDynamic = mass != 0.f; + btRigidBody* body = createRigidBody(isDynamic, mass, startTransform, shape, colObjData->m_collisionObjectData.m_name); + body->setFriction(colObjData->m_collisionObjectData.m_friction); + body->setRestitution(colObjData->m_collisionObjectData.m_restitution); + btVector3 linearFactor, angularFactor; + linearFactor.deSerializeFloat(colObjData->m_linearFactor); + angularFactor.deSerializeFloat(colObjData->m_angularFactor); + body->setLinearFactor(linearFactor); + body->setAngularFactor(angularFactor); + +#ifdef USE_INTERNAL_EDGE_UTILITY + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; + if (trimesh->getTriangleInfoMap()) + { + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + } + } +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData, body); + } + else + { + printf("error: no shape found\n"); + } +} + +void btWorldImporter::convertRigidBodyDouble(btRigidBodyDoubleData* colObjData) +{ + btScalar mass = btScalar(colObjData->m_inverseMass ? 1.f / colObjData->m_inverseMass : 0.f); + btVector3 localInertia; + localInertia.setZero(); + btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionObjectData.m_collisionShape); + if (shapePtr && *shapePtr) + { + btTransform startTransform; + colObjData->m_collisionObjectData.m_worldTransform.m_origin.m_floats[3] = 0.f; + startTransform.deSerializeDouble(colObjData->m_collisionObjectData.m_worldTransform); + + // startTransform.setBasis(btMatrix3x3::getIdentity()); + btCollisionShape* shape = (btCollisionShape*)*shapePtr; + if (shape->isNonMoving()) + { + mass = 0.f; + } + if (mass) + { + shape->calculateLocalInertia(mass, localInertia); + } + bool isDynamic = mass != 0.f; + btRigidBody* body = createRigidBody(isDynamic, mass, startTransform, shape, colObjData->m_collisionObjectData.m_name); + body->setFriction(btScalar(colObjData->m_collisionObjectData.m_friction)); + body->setRestitution(btScalar(colObjData->m_collisionObjectData.m_restitution)); + btVector3 linearFactor, angularFactor; + linearFactor.deSerializeDouble(colObjData->m_linearFactor); + angularFactor.deSerializeDouble(colObjData->m_angularFactor); + body->setLinearFactor(linearFactor); + body->setAngularFactor(angularFactor); + +#ifdef USE_INTERNAL_EDGE_UTILITY + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; + if (trimesh->getTriangleInfoMap()) + { + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + } + } +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData, body); + } + else + { + printf("error: no shape found\n"); + } +} diff --git a/extern/bullet3/Serialize/BulletWorldImporter/btWorldImporter.h b/extern/bullet3/Serialize/BulletWorldImporter/btWorldImporter.h new file mode 100644 index 0000000..ba087fb --- /dev/null +++ b/extern/bullet3/Serialize/BulletWorldImporter/btWorldImporter.h @@ -0,0 +1,227 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2012 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. 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. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_WORLD_IMPORTER_H +#define BT_WORLD_IMPORTER_H + +#include "LinearMath/btTransform.h" +#include "LinearMath/btVector3.h" +#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btHashMap.h" + +class btCollisionShape; +class btCollisionObject; +class btRigidBody; +class btTypedConstraint; +class btDynamicsWorld; +struct ConstraintInput; +class btRigidBodyColladaInfo; +struct btCollisionShapeData; +class btTriangleIndexVertexArray; +class btStridingMeshInterface; +struct btStridingMeshInterfaceData; +class btGImpactMeshShape; +class btOptimizedBvh; +struct btTriangleInfoMap; +class btBvhTriangleMeshShape; +class btPoint2PointConstraint; +class btHingeConstraint; +class btConeTwistConstraint; +class btGeneric6DofConstraint; +class btGeneric6DofSpringConstraint; +class btGeneric6DofSpring2Constraint; +class btSliderConstraint; +class btGearConstraint; +struct btContactSolverInfo; +struct btTypedConstraintData; +struct btTypedConstraintFloatData; +struct btTypedConstraintDoubleData; + +struct btRigidBodyDoubleData; +struct btRigidBodyFloatData; + +#ifdef BT_USE_DOUBLE_PRECISION +#define btRigidBodyData btRigidBodyDoubleData +#else +#define btRigidBodyData btRigidBodyFloatData +#endif //BT_USE_DOUBLE_PRECISION + +enum btWorldImporterFlags +{ + eRESTORE_EXISTING_OBJECTS = 1, //don't create new objects +}; + +class btWorldImporter +{ +protected: + btDynamicsWorld* m_dynamicsWorld; + + int m_verboseMode; + int m_importerFlags; + + btAlignedObjectArray m_allocatedCollisionShapes; + btAlignedObjectArray m_allocatedRigidBodies; + btAlignedObjectArray m_allocatedConstraints; + btAlignedObjectArray m_allocatedBvhs; + btAlignedObjectArray m_allocatedTriangleInfoMaps; + btAlignedObjectArray m_allocatedTriangleIndexArrays; + btAlignedObjectArray m_allocatedbtStridingMeshInterfaceDatas; + + btAlignedObjectArray m_allocatedNames; + + btAlignedObjectArray m_indexArrays; + btAlignedObjectArray m_shortIndexArrays; + btAlignedObjectArray m_charIndexArrays; + + btAlignedObjectArray m_floatVertexArrays; + btAlignedObjectArray m_doubleVertexArrays; + + btHashMap m_bvhMap; + btHashMap m_timMap; + + btHashMap m_nameShapeMap; + btHashMap m_nameBodyMap; + btHashMap m_nameConstraintMap; + btHashMap m_objectNameMap; + + btHashMap m_shapeMap; + btHashMap m_bodyMap; + + //methods + + static btRigidBody& getFixedBody(); + + char* duplicateName(const char* name); + + btCollisionShape* convertCollisionShape(btCollisionShapeData* shapeData); + + void convertConstraintBackwardsCompatible281(btTypedConstraintData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion); + void convertConstraintFloat(btTypedConstraintFloatData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion); + void convertConstraintDouble(btTypedConstraintDoubleData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion); + void convertRigidBodyFloat(btRigidBodyFloatData* colObjData); + void convertRigidBodyDouble(btRigidBodyDoubleData* colObjData); + +public: + btWorldImporter(btDynamicsWorld* world); + + virtual ~btWorldImporter(); + + ///delete all memory collision shapes, rigid bodies, constraints etc. allocated during the load. + ///make sure you don't use the dynamics world containing objects after you call this method + virtual void deleteAllData(); + + void setVerboseMode(int verboseMode) + { + m_verboseMode = verboseMode; + } + + int getVerboseMode() const + { + return m_verboseMode; + } + + void setImporterFlags(int importerFlags) + { + m_importerFlags = importerFlags; + } + + int getImporterFlags() const + { + return m_importerFlags; + } + + // query for data + int getNumCollisionShapes() const; + btCollisionShape* getCollisionShapeByIndex(int index); + int getNumRigidBodies() const; + btCollisionObject* getRigidBodyByIndex(int index) const; + int getNumConstraints() const; + btTypedConstraint* getConstraintByIndex(int index) const; + int getNumBvhs() const; + btOptimizedBvh* getBvhByIndex(int index) const; + int getNumTriangleInfoMaps() const; + btTriangleInfoMap* getTriangleInfoMapByIndex(int index) const; + + // queris involving named objects + btCollisionShape* getCollisionShapeByName(const char* name); + btRigidBody* getRigidBodyByName(const char* name); + btTypedConstraint* getConstraintByName(const char* name); + const char* getNameForPointer(const void* ptr) const; + + ///those virtuals are called by load and can be overridden by the user + + virtual void setDynamicsWorldInfo(const btVector3& gravity, const btContactSolverInfo& solverInfo); + + //bodies + virtual btRigidBody* createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform, btCollisionShape* shape, const char* bodyName); + virtual btCollisionObject* createCollisionObject(const btTransform& startTransform, btCollisionShape* shape, const char* bodyName); + + ///shapes + + virtual btCollisionShape* createPlaneShape(const btVector3& planeNormal, btScalar planeConstant); + virtual btCollisionShape* createBoxShape(const btVector3& halfExtents); + virtual btCollisionShape* createSphereShape(btScalar radius); + virtual btCollisionShape* createCapsuleShapeX(btScalar radius, btScalar height); + virtual btCollisionShape* createCapsuleShapeY(btScalar radius, btScalar height); + virtual btCollisionShape* createCapsuleShapeZ(btScalar radius, btScalar height); + + virtual btCollisionShape* createCylinderShapeX(btScalar radius, btScalar height); + virtual btCollisionShape* createCylinderShapeY(btScalar radius, btScalar height); + virtual btCollisionShape* createCylinderShapeZ(btScalar radius, btScalar height); + virtual btCollisionShape* createConeShapeX(btScalar radius, btScalar height); + virtual btCollisionShape* createConeShapeY(btScalar radius, btScalar height); + virtual btCollisionShape* createConeShapeZ(btScalar radius, btScalar height); + virtual class btTriangleIndexVertexArray* createTriangleMeshContainer(); + virtual btBvhTriangleMeshShape* createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh); + virtual btCollisionShape* createConvexTriangleMeshShape(btStridingMeshInterface* trimesh); + virtual btGImpactMeshShape* createGimpactShape(btStridingMeshInterface* trimesh); + virtual btStridingMeshInterfaceData* createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData); + + virtual class btConvexHullShape* createConvexHullShape(); + virtual class btCompoundShape* createCompoundShape(); + virtual class btScaledBvhTriangleMeshShape* createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape, const btVector3& localScalingbtBvhTriangleMeshShape); + + virtual class btMultiSphereShape* createMultiSphereShape(const btVector3* positions, const btScalar* radi, int numSpheres); + + virtual btTriangleIndexVertexArray* createMeshInterface(btStridingMeshInterfaceData& meshData); + + virtual class btHeightfieldTerrainShape* createHeightfieldShape(int heightStickWidth, int heightStickLength, + const void* heightfieldData, btScalar heightScale, + btScalar minHeight, btScalar maxHeight, + int upAxis, int heightDataType, + bool flipQuadEdges); + + ///acceleration and connectivity structures + virtual btOptimizedBvh* createOptimizedBvh(); + virtual btTriangleInfoMap* createTriangleInfoMap(); + + ///constraints + virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& pivotInA, const btVector3& pivotInB); + virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA, const btVector3& pivotInA); + virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false); + virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA, const btTransform& rbAFrame, bool useReferenceFrameA = false); + virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame); + virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA, const btTransform& rbAFrame); + virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA); + virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB); + virtual btGeneric6DofSpringConstraint* createGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA); + virtual btGeneric6DofSpring2Constraint* createGeneric6DofSpring2Constraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, int rotateOrder); + + virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA); + virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA); + virtual btGearConstraint* createGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA, const btVector3& axisInB, btScalar ratio); +}; + +#endif //BT_WORLD_IMPORTER_H \ No newline at end of file diff --git a/extern/lua/CMakeLists.txt b/extern/lua/CMakeLists.txt index c305628..3d39712 100644 --- a/extern/lua/CMakeLists.txt +++ b/extern/lua/CMakeLists.txt @@ -99,6 +99,8 @@ if(WIN32) target_compile_definitions(libluadll PRIVATE _CRT_SECURE_NO_WARNINGS LUA_BUILD_AS_DLL) elseif(CMAKE_SYSTEM_NAME MATCHES "Linux") target_compile_definitions(libluadll PUBLIC LUA_USE_LINUX) +elseif(APPLE) + target_compile_definitions(libluadll PUBLIC LUA_USE_MACOSX) endif() set_target_properties(libluadll PROPERTIES OUTPUT_NAME lua54)