Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-03-18 00:44:58 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-03-18 00:44:58 +0300
commitd52400bfbd2a7e4d09b5a71bc461a554d232af15 (patch)
tree08815f065fc90aac0ae62ae5f3a89d20e19399e6
parent1ac0d54fea831c485e8e27e8bfa887e15beb58de (diff)
parent28f6d223d079b1e5cb67e3fc22fb7f818deb8dcb (diff)
2.50: svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r18677:19317
Notes: * Sequence transform strip uses G.scene global, this is commented out now, should be fixed. * Etch-a-ton code was most difficult to merge. The files already in 2.5 got merged, but no new files were added. Calls to these files are commented out with "XXX etch-a-ton". editarmature.c and transform_snap.c were complex to merge. Martin, please check? * Game engine compiles and links again here for scons/make/cmake (player still fails to link).
-rw-r--r--CMakeLists.txt4
-rw-r--r--SConstruct1
-rw-r--r--blenderplayer/CMakeLists.txt1
-rw-r--r--extern/CMakeLists.txt5
-rw-r--r--extern/Makefile4
-rw-r--r--extern/SConscript4
-rw-r--r--extern/bullet2/make/msvc_9_0/Bullet.vcproj24
-rw-r--r--extern/bullet2/src/Bullet-C-Api.h18
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp9
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h180
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h22
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h45
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.cpp1512
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.h1297
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp755
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h116
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h17
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp25
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h9
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp82
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h37
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp193
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h69
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp58
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h31
-rw-r--r--extern/bullet2/src/BulletCollision/CMakeLists.txt383
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp18
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp47
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h36
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp14
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h1
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp19
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp1
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h44
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp289
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h47
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp69
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h11
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h7
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp204
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h39
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp85
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h29
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp12
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h16
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.cpp171
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.h174
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h3
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp166
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h16
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h36
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp58
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h7
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp3
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp10
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h15
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp65
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h26
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h10
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h3
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp45
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h42
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp5
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h11
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp156
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h96
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp361
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h26
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp18
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h10
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.cpp3
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp251
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h108
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp10
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp3
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h1
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h11
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp26
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp5
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h25
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp11
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h7
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h9
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp3
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h5
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h23
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp35
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h21
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp1
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp52
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp5
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h17
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp3
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h1
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btBoxCollision.h8
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btClipPolygon.h4
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btContactProcessing.cpp6
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btContactProcessing.h24
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGImpactBvh.cpp15
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGImpactBvh.h47
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp13
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h6
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp17
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h21
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h17
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp6
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGenericPoolAllocator.h5
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGeometryOperations.h4
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btQuantization.h4
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btTriangleShapeEx.cpp8
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btTriangleShapeEx.h10
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_array.h8
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_basic_geometry_operations.h4
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_bitset.h6
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_box_collision.h4
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_box_set.cpp4
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_box_set.h7
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_clip_polygon.h4
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_contact.h16
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_geom_types.h7
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_hash_table.h26
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_linear_math.h11
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_math.h32
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_memory.h47
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_radixsort.h8
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_tri_collision.cpp6
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_tri_collision.h6
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp8
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h3
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp1420
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp13
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h2
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp70
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h11
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h8
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp19
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h3
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp11
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h20
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp20
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h13
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h7
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp24
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h22
-rw-r--r--extern/bullet2/src/BulletDynamics/CMakeLists.txt93
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp948
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h109
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp14
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h2
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h16
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp865
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h55
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp667
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h30
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp207
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h9
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp1775
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h72
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp462
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h15
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h162
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h62
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp64
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h66
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp22
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btActionInterface.h39
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp3
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp424
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h50
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h19
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp15
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h69
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp6
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h4
-rw-r--r--extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp49
-rw-r--r--extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h42
-rw-r--r--extern/bullet2/src/BulletSoftBody/CMakeLists.txt36
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBody.cpp2043
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBody.h291
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp120
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h12
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.cpp478
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.h86
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBodyInternals.h747
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp18
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h2
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp6
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h8
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp41
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.h18
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h2
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSparseSDF.h178
-rw-r--r--extern/bullet2/src/LinearMath/CMakeLists.txt28
-rw-r--r--extern/bullet2/src/LinearMath/btAabbUtil2.h52
-rw-r--r--extern/bullet2/src/LinearMath/btAlignedAllocator.cpp30
-rw-r--r--extern/bullet2/src/LinearMath/btAlignedAllocator.h7
-rw-r--r--extern/bullet2/src/LinearMath/btAlignedObjectArray.h26
-rw-r--r--extern/bullet2/src/LinearMath/btConvexHull.cpp62
-rw-r--r--extern/bullet2/src/LinearMath/btConvexHull.h20
-rw-r--r--extern/bullet2/src/LinearMath/btIDebugDraw.h181
-rw-r--r--extern/bullet2/src/LinearMath/btMatrix3x3.h238
-rw-r--r--extern/bullet2/src/LinearMath/btQuadWord.h196
-rw-r--r--extern/bullet2/src/LinearMath/btQuaternion.h164
-rw-r--r--extern/bullet2/src/LinearMath/btQuickprof.cpp66
-rw-r--r--extern/bullet2/src/LinearMath/btQuickprof.h20
-rw-r--r--extern/bullet2/src/LinearMath/btScalar.h32
-rw-r--r--extern/bullet2/src/LinearMath/btStackAlloc.h1
-rw-r--r--extern/bullet2/src/LinearMath/btTransform.h66
-rw-r--r--extern/bullet2/src/LinearMath/btTransformUtil.h123
-rw-r--r--extern/bullet2/src/LinearMath/btVector3.h341
-rw-r--r--extern/bullet2/src/SConscript2
-rw-r--r--extern/libopenjpeg/CMakeLists.txt32
-rw-r--r--extern/libopenjpeg/Makefile43
-rw-r--r--extern/libopenjpeg/SConscript1
-rw-r--r--extern/libopenjpeg/t1_generate_luts.c275
-rw-r--r--extern/libredcode/codec.c2
-rw-r--r--extern/libredcode/format.c78
-rw-r--r--extern/libredcode/format.h4
-rw-r--r--intern/SoundSystem/openal/SND_OpenALDevice.cpp14
-rw-r--r--intern/SoundSystem/openal/SND_OpenALDevice.h2
-rw-r--r--intern/SoundSystem/sdl/SND_SDLCDDevice.h2
-rw-r--r--intern/decimation/SConscript2
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp48
-rw-r--r--intern/opennl/SConscript4
-rw-r--r--intern/opennl/superlu/get_perm_c.c4
-rw-r--r--projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj8
-rw-r--r--projectfiles_vc9/blender/nodes/nodes.vcproj16
-rw-r--r--projectfiles_vc9/gameengine/blenderhook/KX_blenderhook.vcproj5
-rw-r--r--projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj8
-rw-r--r--projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj4
-rw-r--r--release/freedesktop/blender.desktop10
-rw-r--r--release/scripts/bpymodules/paths_svg2obj.py178
-rw-r--r--release/scripts/export_fbx.py4
-rw-r--r--release/scripts/export_obj.py2
-rw-r--r--release/scripts/import_dxf.py402
-rw-r--r--release/scripts/import_obj.py4
-rwxr-xr-xrelease/scripts/import_web3d.py2
-rw-r--r--release/scripts/ply_import.py19
-rw-r--r--release/scripts/scripttemplate_gamelogic.py5
-rw-r--r--source/Makefile10
-rw-r--r--source/blender/Makefile5
-rw-r--r--source/blender/blenkernel/BKE_node.h4
-rw-r--r--source/blender/blenkernel/CMakeLists.txt4
-rw-r--r--source/blender/blenkernel/SConscript2
-rw-r--r--source/blender/blenkernel/intern/Makefile4
-rw-r--r--source/blender/blenkernel/intern/modifier.c17
-rw-r--r--source/blender/blenkernel/intern/node.c14
-rw-r--r--source/blender/blenkernel/intern/object.c1
-rw-r--r--source/blender/blenkernel/intern/particle_system.c2
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c24
-rw-r--r--source/blender/blenkernel/intern/sequence.c21
-rw-r--r--source/blender/blenkernel/intern/softbody.c6
-rw-r--r--source/blender/blenlib/BLI_arithb.h2
-rw-r--r--source/blender/blenlib/BLI_graph.h33
-rw-r--r--source/blender/blenlib/intern/arithb.c112
-rw-r--r--source/blender/blenlib/intern/bpath.c4
-rw-r--r--source/blender/blenlib/intern/graph.c58
-rw-r--r--source/blender/blenloader/intern/readfile.c52
-rw-r--r--source/blender/blenloader/intern/writefile.c2
-rw-r--r--source/blender/blenpluginapi/iff.h6
-rw-r--r--source/blender/editors/CMakeLists.txt4
-rw-r--r--source/blender/editors/armature/armature_intern.h21
-rw-r--r--source/blender/editors/armature/editarmature.c468
-rw-r--r--source/blender/editors/armature/reeb.h35
-rw-r--r--source/blender/editors/curve/editcurve.c58
-rw-r--r--source/blender/editors/gpencil/gpencil.c2
-rw-r--r--source/blender/editors/include/BIF_transform.h29
-rw-r--r--source/blender/editors/include/ED_armature.h2
-rw-r--r--source/blender/editors/include/ED_view3d.h1
-rw-r--r--source/blender/editors/interface/interface.c9
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c8
-rw-r--r--source/blender/editors/space_buttons/SConscript10
-rw-r--r--source/blender/editors/space_file/Makefile5
-rw-r--r--source/blender/editors/space_image/image_panels.c1
-rw-r--r--source/blender/editors/space_info/SConscript10
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c2
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c5
-rw-r--r--source/blender/editors/space_view3d/drawobject.c16
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c139
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c37
-rw-r--r--source/blender/editors/transform/transform_conversions.c4
-rw-r--r--source/blender/editors/transform/transform_snap.c947
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c45
-rw-r--r--source/blender/gpu/GPU_draw.h2
-rw-r--r--source/blender/gpu/intern/gpu_draw.c16
-rw-r--r--source/blender/imbuf/CMakeLists.txt5
-rw-r--r--source/blender/imbuf/intern/Makefile4
-rw-r--r--source/blender/imbuf/intern/cineon/cineon_dpx.c11
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.c32
-rw-r--r--source/blender/imbuf/intern/radiance_hdr.c18
-rw-r--r--source/blender/makesdna/DNA_curve_types.h4
-rw-r--r--source/blender/makesdna/DNA_object_types.h6
-rw-r--r--source/blender/makesdna/DNA_scene_types.h38
-rw-r--r--source/blender/makesdna/DNA_sensor_types.h1
-rw-r--r--source/blender/makesdna/DNA_space_types.h1
-rw-r--r--source/blender/nodes/TEX_node.h5
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_blur.c5
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_compose.c71
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_decompose.c92
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c34
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_math.c23
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_proc.c34
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_rotate.c2
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_scale.c76
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_translate.c2
-rw-r--r--source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c92
-rw-r--r--source/blender/quicktime/apple/quicktime_import.c1
-rw-r--r--source/blender/yafray/intern/export_ri.cpp0
-rw-r--r--source/creator/CMakeLists.txt3
-rw-r--r--source/creator/Makefile3
-rw-r--r--source/creator/creator.c2
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp2
-rw-r--r--source/gameengine/BlenderRoutines/CMakeLists.txt4
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp9
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h4
-rw-r--r--source/gameengine/BlenderRoutines/Makefile3
-rw-r--r--source/gameengine/BlenderRoutines/SConscript17
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.cpp10
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.h4
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp109
-rw-r--r--source/gameengine/Converter/BL_MeshDeformer.cpp4
-rw-r--r--source/gameengine/Converter/BL_ShapeActionActuator.cpp10
-rw-r--r--source/gameengine/Converter/BL_ShapeActionActuator.h6
-rw-r--r--source/gameengine/Converter/KX_BlenderSceneConverter.cpp30
-rw-r--r--source/gameengine/Converter/KX_ConvertControllers.cpp7
-rw-r--r--source/gameengine/Converter/KX_ConvertSensors.cpp8
-rw-r--r--source/gameengine/Converter/KX_IpoConvert.cpp50
-rw-r--r--source/gameengine/Converter/SConscript13
-rw-r--r--source/gameengine/Expressions/FloatValue.cpp6
-rw-r--r--source/gameengine/Expressions/InputParser.cpp29
-rw-r--r--source/gameengine/Expressions/InputParser.h1
-rw-r--r--source/gameengine/Expressions/IntValue.cpp6
-rw-r--r--source/gameengine/Expressions/ListValue.cpp109
-rw-r--r--source/gameengine/Expressions/ListValue.h10
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.cpp63
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.h94
-rw-r--r--source/gameengine/Expressions/SConscript7
-rw-r--r--source/gameengine/Expressions/Value.cpp65
-rw-r--r--source/gameengine/Expressions/Value.h7
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp8
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.cpp5
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.h2
-rw-r--r--source/gameengine/GameLogic/SCA_ANDController.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_ANDController.h2
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorSensor.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_ActuatorSensor.h4
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysSensor.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysSensor.h2
-rw-r--r--source/gameengine/GameLogic/SCA_DelaySensor.cpp16
-rw-r--r--source/gameengine/GameLogic/SCA_DelaySensor.h4
-rw-r--r--source/gameengine/GameLogic/SCA_ExpressionController.cpp35
-rw-r--r--source/gameengine/GameLogic/SCA_ExpressionController.h8
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.h2
-rw-r--r--source/gameengine/GameLogic/SCA_IController.cpp4
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_ILogicBrick.h5
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.cpp11
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.h2
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.cpp20
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h9
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickSensor.cpp18
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickSensor.h4
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.cpp16
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.h4
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.cpp14
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.h4
-rw-r--r--source/gameengine/GameLogic/SCA_NANDController.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_NANDController.h2
-rw-r--r--source/gameengine/GameLogic/SCA_NORController.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_NORController.h2
-rw-r--r--source/gameengine/GameLogic/SCA_ORController.cpp7
-rw-r--r--source/gameengine/GameLogic/SCA_ORController.h2
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyActuator.cpp8
-rw-r--r--source/gameengine/GameLogic/SCA_PropertyActuator.h4
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.cpp10
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.h8
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.cpp198
-rw-r--r--source/gameengine/GameLogic/SCA_PythonController.h9
-rw-r--r--source/gameengine/GameLogic/SCA_RandomActuator.cpp32
-rw-r--r--source/gameengine/GameLogic/SCA_RandomActuator.h4
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.cpp10
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.h4
-rw-r--r--source/gameengine/GameLogic/SCA_XNORController.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_XNORController.h2
-rw-r--r--source/gameengine/GameLogic/SCA_XORController.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_XORController.h2
-rw-r--r--source/gameengine/GameLogic/SConscript7
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.cpp9
-rw-r--r--source/gameengine/GamePlayer/common/GPC_RenderTools.h4
-rw-r--r--source/gameengine/GamePlayer/common/SConscript17
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp75
-rw-r--r--source/gameengine/GamePlayer/ghost/SConscript15
-rw-r--r--source/gameengine/Ketsji/BL_Shader.cpp59
-rw-r--r--source/gameengine/Ketsji/BL_Shader.h4
-rw-r--r--source/gameengine/Ketsji/BL_Texture.cpp2
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp14
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h2
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp6
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h2
-rw-r--r--source/gameengine/Ketsji/KXNetwork/SConscript8
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.cpp17
-rw-r--r--source/gameengine/Ketsji/KX_BlenderMaterial.h4
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_CDActuator.cpp14
-rw-r--r--source/gameengine/Ketsji/KX_CDActuator.h2
-rw-r--r--source/gameengine/Ketsji/KX_Camera.cpp167
-rw-r--r--source/gameengine/Ketsji/KX_Camera.h26
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.cpp76
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.h17
-rw-r--r--source/gameengine/Ketsji/KX_ClientObjectInfo.h16
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.cpp28
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.h2
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintWrapper.cpp18
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintWrapper.h4
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObject.h10
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp20
-rw-r--r--source/gameengine/Ketsji/KX_GameActuator.cpp10
-rw-r--r--source/gameengine/Ketsji/KX_GameActuator.h2
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp158
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h21
-rw-r--r--source/gameengine/Ketsji/KX_IPO_SGController.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_IpoActuator.cpp22
-rw-r--r--source/gameengine/Ketsji/KX_IpoActuator.h2
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp10
-rw-r--r--source/gameengine/Ketsji/KX_Light.cpp64
-rw-r--r--source/gameengine/Ketsji/KX_Light.h4
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.cpp8
-rw-r--r--source/gameengine/Ketsji/KX_MeshProxy.h2
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.cpp97
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.h14
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.cpp48
-rw-r--r--source/gameengine/Ketsji/KX_NearSensor.h29
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.cpp34
-rw-r--r--source/gameengine/Ketsji/KX_ObjectActuator.h2
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.cpp40
-rw-r--r--source/gameengine/Ketsji/KX_ParentActuator.h3
-rw-r--r--source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp10
-rw-r--r--source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h4
-rw-r--r--source/gameengine/Ketsji/KX_PolyProxy.cpp31
-rw-r--r--source/gameengine/Ketsji/KX_PolyProxy.h2
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.cpp75
-rw-r--r--source/gameengine/Ketsji/KX_PolygonMaterial.h4
-rw-r--r--source/gameengine/Ketsji/KX_PyMath.cpp57
-rw-r--r--source/gameengine/Ketsji/KX_PyMath.h14
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp83
-rw-r--r--source/gameengine/Ketsji/KX_RadarSensor.cpp134
-rw-r--r--source/gameengine/Ketsji/KX_RadarSensor.h28
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.cpp72
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.h10
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp46
-rw-r--r--source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h15
-rw-r--r--source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp7
-rw-r--r--source/gameengine/Ketsji/KX_SCA_DynamicActuator.h5
-rw-r--r--source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h5
-rw-r--r--source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h5
-rw-r--r--source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp19
-rw-r--r--source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp80
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp94
-rw-r--r--source/gameengine/Ketsji/KX_Scene.h15
-rw-r--r--source/gameengine/Ketsji/KX_SceneActuator.cpp14
-rw-r--r--source/gameengine/Ketsji/KX_SceneActuator.h2
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.cpp32
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.h2
-rw-r--r--source/gameengine/Ketsji/KX_StateActuator.cpp13
-rw-r--r--source/gameengine/Ketsji/KX_StateActuator.h2
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.cpp186
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.h35
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.cpp52
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.h3
-rw-r--r--source/gameengine/Ketsji/KX_VehicleWrapper.cpp7
-rw-r--r--source/gameengine/Ketsji/KX_VehicleWrapper.h4
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.cpp247
-rw-r--r--source/gameengine/Ketsji/KX_VertexProxy.h24
-rw-r--r--source/gameengine/Ketsji/KX_VisibilityActuator.cpp11
-rw-r--r--source/gameengine/Ketsji/KX_VisibilityActuator.h2
-rw-r--r--source/gameengine/Ketsji/SConscript25
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp29
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h2
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp24
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h2
-rw-r--r--source/gameengine/Physics/Bullet/SConscript8
-rw-r--r--source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h2
-rw-r--r--source/gameengine/Physics/common/PHY_DynamicTypes.h2
-rw-r--r--source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h2
-rw-r--r--source/gameengine/Physics/common/SConscript7
-rw-r--r--source/gameengine/PyDoc/GameLogic.py10
-rw-r--r--source/gameengine/PyDoc/KX_CameraActuator.py10
-rw-r--r--source/gameengine/PyDoc/KX_GameObject.py2
-rw-r--r--source/gameengine/PyDoc/KX_NearSensor.py5
-rw-r--r--source/gameengine/PyDoc/KX_ParentActuator.py3
-rw-r--r--source/gameengine/PyDoc/KX_RadarSensor.py18
-rw-r--r--source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py4
-rw-r--r--source/gameengine/PyDoc/KX_Scene.py15
-rw-r--r--source/gameengine/PyDoc/KX_TouchSensor.py37
-rw-r--r--source/gameengine/PyDoc/KX_TrackToActuator.py2
-rw-r--r--source/gameengine/PyDoc/SCA_DelaySensor.py7
-rw-r--r--source/gameengine/PyDoc/SCA_PythonController.py12
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp2
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.h2
-rw-r--r--source/gameengine/Rasterizer/RAS_IRasterizer.h4
-rw-r--r--source/gameengine/Rasterizer/RAS_IRenderTools.h1
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.cpp4
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp27
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h4
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript7
-rw-r--r--source/gameengine/Rasterizer/RAS_TexVert.cpp26
-rw-r--r--source/gameengine/Rasterizer/RAS_TexVert.h3
-rw-r--r--source/gameengine/Rasterizer/SConscript10
-rw-r--r--source/gameengine/SConscript4
-rw-r--r--source/gameengine/SceneGraph/SConscript7
-rw-r--r--source/gameengine/SceneGraph/SG_BBox.cpp4
-rw-r--r--source/gameengine/SceneGraph/SG_Spatial.cpp19
-rw-r--r--source/gameengine/SceneGraph/SG_Spatial.h2
-rw-r--r--source/gameengine/VideoTexture/CMakeLists.txt2
-rw-r--r--source/gameengine/VideoTexture/FilterBase.cpp2
-rw-r--r--source/gameengine/VideoTexture/FilterSource.h8
-rw-r--r--source/gameengine/VideoTexture/Makefile3
-rw-r--r--source/gameengine/VideoTexture/SConscript13
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.cpp538
-rw-r--r--source/gameengine/VideoTexture/VideoFFmpeg.h46
-rw-r--r--source/kernel/SConscript2
-rw-r--r--source/nan_definitions.mk7
-rw-r--r--tools/Blender.py6
-rwxr-xr-xtools/btools.py3
555 files changed, 19794 insertions, 11572 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2d70716a468..45caf48091b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,6 +63,7 @@ OPTION(WITH_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON)
OPTION(WITH_DDS "Enable DDS Support" ON)
OPTION(WITH_FFMPEG "Enable FFMPeg Support (http://ffmpeg.mplayerhq.hu/)" OFF)
OPTION(WITH_PYTHON "Enable Embedded Python API" ON)
+OPTION(WITH_OPENJPEG "Enable OpenJpeg Support (http://www.openjpeg.org/)" OFF)
OPTION(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON)
OPTION(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" OFF)
OPTION(WITH_WEBPLUGIN "Enable Web Plugin (Unix only)" OFF)
@@ -439,6 +440,9 @@ SET(FTGL ${CMAKE_SOURCE_DIR}/extern/bFTGL)
SET(FTGL_INC ${FTGL}/include)
SET(FTGL_LIB extern_ftgl)
+set(OPENJPEG ${CMAKE_SOURCE_DIR}/extern/libopenjpeg)
+set(OPENJPEG_INC ${OPENJPEG})
+set(OPENJPEG_LIb extern_libopenjpeg)
#-----------------------------------------------------------------------------
# Blender WebPlugin
diff --git a/SConstruct b/SConstruct
index 72acbf845d7..c91b44e3659 100644
--- a/SConstruct
+++ b/SConstruct
@@ -288,6 +288,7 @@ if 'blenderlite' in B.targets:
env['WITH_BF_PNG'] = False
env['WITH_BF_ODE'] = False
env['WITH_BF_BULLET'] = False
+ env['WITH_BF_SOLID'] = False
env['WITH_BF_BINRELOC'] = False
env['BF_BUILDINFO'] = False
env['BF_NO_ELBEEM'] = True
diff --git a/blenderplayer/CMakeLists.txt b/blenderplayer/CMakeLists.txt
index f02650f7ea0..b9ac3c7a8c6 100644
--- a/blenderplayer/CMakeLists.txt
+++ b/blenderplayer/CMakeLists.txt
@@ -104,6 +104,7 @@ IF(UNIX)
bf_blenlib
bf_cineon
bf_openexr
+ extern_libopenjpeg
bf_dds
bf_ftfont
extern_ftgl
diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt
index ee5cab31e09..b81efb52de9 100644
--- a/extern/CMakeLists.txt
+++ b/extern/CMakeLists.txt
@@ -29,7 +29,7 @@ IF(WITH_GAMEENGINE)
ENDIF(WITH_GAMEENGINE)
IF(WITH_BULLET)
- SUBDIRS(bullet2)
+ SUBDIRS(bullet2)
ENDIF(WITH_BULLET)
IF(WITH_INTERNATIONAL)
@@ -46,3 +46,6 @@ ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
SUBDIRS(glew)
+IF(WITH_OPENJPEG)
+ SUBDIRS(libopenjpeg)
+ENDIF(WITH_OPENJPEG)
diff --git a/extern/Makefile b/extern/Makefile
index 51213698ebb..38bec4b73dd 100644
--- a/extern/Makefile
+++ b/extern/Makefile
@@ -57,6 +57,10 @@ ifeq ($(WITH_BINRELOC), true)
DIRS += binreloc
endif
+ifeq ($(WITH_OPENJPEG), true)
+ DIRS += libopenjpeg
+endif
+
TARGET = solid
all::
diff --git a/extern/SConscript b/extern/SConscript
index 972d2a8e703..716aee8991f 100644
--- a/extern/SConscript
+++ b/extern/SConscript
@@ -5,8 +5,8 @@ Import('env')
SConscript(['glew/SConscript'])
if env['WITH_BF_GAMEENGINE']:
- SConscript(['qhull/SConscript',
- 'solid/SConscript'])
+ if env['WITH_BF_SOLID']:
+ SConscript(['qhull/SConscript', 'solid/SConscript'])
if env['WITH_BF_BULLET']:
SConscript(['bullet2/src/SConscript'])
diff --git a/extern/bullet2/make/msvc_9_0/Bullet.vcproj b/extern/bullet2/make/msvc_9_0/Bullet.vcproj
index d22b98efade..6ec064913a5 100644
--- a/extern/bullet2/make/msvc_9_0/Bullet.vcproj
+++ b/extern/bullet2/make/msvc_9_0/Bullet.vcproj
@@ -729,6 +729,14 @@
Name="CollisionDispatch"
>
<File
+ RelativePath="..\..\src\BulletCollision\CollisionDispatch\btActivatingCollisionAlgorithm.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\BulletCollision\CollisionDispatch\btActivatingCollisionAlgorithm.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\BulletCollision\CollisionDispatch\btBoxBoxCollisionAlgorithm.cpp"
>
</File>
@@ -825,6 +833,14 @@
>
</File>
<File
+ RelativePath="..\..\src\BulletCollision\CollisionDispatch\btGhostObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\BulletCollision\CollisionDispatch\btGhostObject.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\BulletCollision\CollisionDispatch\btManifoldResult.cpp"
>
</File>
@@ -961,6 +977,14 @@
>
</File>
<File
+ RelativePath="..\..\src\BulletCollision\CollisionShapes\btConvexPointCloudShape.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\BulletCollision\CollisionShapes\btConvexPointCloudShape.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\BulletCollision\CollisionShapes\btConvexShape.cpp"
>
</File>
diff --git a/extern/bullet2/src/Bullet-C-Api.h b/extern/bullet2/src/Bullet-C-Api.h
index 8074aed3038..a4a8a70524e 100644
--- a/extern/bullet2/src/Bullet-C-Api.h
+++ b/extern/bullet2/src/Bullet-C-Api.h
@@ -38,37 +38,37 @@ typedef plReal plQuaternion[4];
extern "C" {
#endif
-/* Particular physics SDK */
+/** Particular physics SDK (C-API) */
PL_DECLARE_HANDLE(plPhysicsSdkHandle);
-/* Dynamics world, belonging to some physics SDK */
+/** Dynamics world, belonging to some physics SDK (C-API)*/
PL_DECLARE_HANDLE(plDynamicsWorldHandle);
-/* Rigid Body that can be part of a Dynamics World */
+/** Rigid Body that can be part of a Dynamics World (C-API)*/
PL_DECLARE_HANDLE(plRigidBodyHandle);
-/* Collision Shape/Geometry, property of a Rigid Body */
+/** Collision Shape/Geometry, property of a Rigid Body (C-API)*/
PL_DECLARE_HANDLE(plCollisionShapeHandle);
-/* Constraint for Rigid Bodies */
+/** Constraint for Rigid Bodies (C-API)*/
PL_DECLARE_HANDLE(plConstraintHandle);
-/* Triangle Mesh interface */
+/** Triangle Mesh interface (C-API)*/
PL_DECLARE_HANDLE(plMeshInterfaceHandle);
-/* Broadphase Scene/Proxy Handles */
+/** Broadphase Scene/Proxy Handles (C-API)*/
PL_DECLARE_HANDLE(plCollisionBroadphaseHandle);
PL_DECLARE_HANDLE(plBroadphaseProxyHandle);
PL_DECLARE_HANDLE(plCollisionWorldHandle);
-/*
+/**
Create and Delete a Physics SDK
*/
extern plPhysicsSdkHandle plNewBulletSdk(); //this could be also another sdk, like ODE, PhysX etc.
extern void plDeletePhysicsSdk(plPhysicsSdkHandle physicsSdk);
-/* Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */
+/** Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */
typedef void(*btBroadphaseCallback)(void* clientData, void* object1,void* object2);
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp
index d7eea33ea41..77763305b1b 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp
@@ -19,10 +19,9 @@
// 3. This notice may not be removed or altered from any source distribution.
#include "btAxisSweep3.h"
-#include <assert.h>
-btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache)
-:btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache)
+btAxisSweep3::btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache, bool disableRaycastAccelerator)
+:btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache,disableRaycastAccelerator)
{
// 1 handle is reserved as sentinel
btAssert(maxHandles > 1 && maxHandles < 32767);
@@ -30,8 +29,8 @@ btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAab
}
-bt32BitAxisSweep3::bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache )
-:btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache)
+bt32BitAxisSweep3::bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache , bool disableRaycastAccelerator)
+:btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache,disableRaycastAccelerator)
{
// 1 handle is reserved as sentinel
btAssert(maxHandles > 1 && maxHandles < 2147483647);
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
index d0ad09a385a..cad21b4cad2 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
@@ -19,12 +19,12 @@
#ifndef AXIS_SWEEP_3_H
#define AXIS_SWEEP_3_H
-#include "LinearMath/btPoint3.h"
#include "LinearMath/btVector3.h"
#include "btOverlappingPairCache.h"
#include "btBroadphaseInterface.h"
#include "btBroadphaseProxy.h"
#include "btOverlappingPairCallback.h"
+#include "btDbvtBroadphase.h"
//#define DEBUG_BROADPHASE 1
#define USE_OVERLAP_TEST_ON_REMOVES 1
@@ -42,6 +42,7 @@ protected:
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
class Edge
{
@@ -61,8 +62,7 @@ public:
// indexes into the edge arrays
BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12
// BP_FP_INT_TYPE m_uniqueId;
- BP_FP_INT_TYPE m_pad;
-
+ btBroadphaseProxy* m_dbvtProxy;//for faster raycast
//void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject
SIMD_FORCE_INLINE void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;}
@@ -71,8 +71,8 @@ public:
protected:
- btPoint3 m_worldAabbMin; // overall system bounds
- btPoint3 m_worldAabbMax; // overall system bounds
+ btVector3 m_worldAabbMin; // overall system bounds
+ btVector3 m_worldAabbMax; // overall system bounds
btVector3 m_quantize; // scaling factor for quantization
@@ -94,6 +94,12 @@ protected:
int m_invalidPair;
+ ///additional dynamic aabb structure, used to accelerate ray cast queries.
+ ///can be disabled using a optional argument in the constructor
+ btDbvtBroadphase* m_raycastAccelerator;
+ btOverlappingPairCache* m_nullPairCache;
+
+
// allocation/deallocation
BP_FP_INT_TYPE allocHandle();
void freeHandle(BP_FP_INT_TYPE handle);
@@ -108,7 +114,7 @@ protected:
//Overlap* AddOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
//void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
- void quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const;
+
void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
@@ -117,7 +123,7 @@ protected:
public:
- btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0);
+ btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0,bool disableRaycastAccelerator = false);
virtual ~btAxisSweep3Internal();
@@ -128,17 +134,26 @@ public:
virtual void calculateOverlappingPairs(btDispatcher* dispatcher);
- BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
+ BP_FP_INT_TYPE addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
void removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher);
- void updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher);
+ void updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;}
+ virtual void resetPool(btDispatcher* dispatcher);
+
void processAllOverlappingPairs(btOverlapCallback* callback);
//Broadphase Interface
virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
+ virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
+
+ virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
+
+ void quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const;
+ ///unQuantize should be conservative: aabbMin/aabbMax should be larger then 'getAabb' result
+ void unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
@@ -206,7 +221,7 @@ void btAxisSweep3<BP_FP_INT_TYPE>::debugPrintAxis(int axis, bool checkCardinalit
}
if (checkCardinality)
- assert(numEdges == m_numHandles*2+1);
+ btAssert(numEdges == m_numHandles*2+1);
}
#endif //DEBUG_BROADPHASE
@@ -217,7 +232,12 @@ btBroadphaseProxy* btAxisSweep3Internal<BP_FP_INT_TYPE>::createProxy( const btV
BP_FP_INT_TYPE handleId = addHandle(aabbMin,aabbMax, userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,multiSapProxy);
Handle* handle = getHandle(handleId);
-
+
+ if (m_raycastAccelerator)
+ {
+ btBroadphaseProxy* rayProxy = m_raycastAccelerator->createProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,0);
+ handle->m_dbvtProxy = rayProxy;
+ }
return handle;
}
@@ -227,6 +247,8 @@ template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
{
Handle* handle = static_cast<Handle*>(proxy);
+ if (m_raycastAccelerator)
+ m_raycastAccelerator->destroyProxy(handle->m_dbvtProxy,dispatcher);
removeHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), dispatcher);
}
@@ -234,22 +256,80 @@ template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher)
{
Handle* handle = static_cast<Handle*>(proxy);
+ handle->m_aabbMin = aabbMin;
+ handle->m_aabbMax = aabbMax;
updateHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), aabbMin, aabbMax,dispatcher);
+ if (m_raycastAccelerator)
+ m_raycastAccelerator->setAabb(handle->m_dbvtProxy,aabbMin,aabbMax,dispatcher);
+
+}
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax)
+{
+ if (m_raycastAccelerator)
+ {
+ m_raycastAccelerator->rayTest(rayFrom,rayTo,rayCallback,aabbMin,aabbMax);
+ } else
+ {
+ //choose axis?
+ BP_FP_INT_TYPE axis = 0;
+ //for each proxy
+ for (BP_FP_INT_TYPE i=1;i<m_numHandles*2+1;i++)
+ {
+ if (m_pEdges[axis][i].IsMax())
+ {
+ rayCallback.process(getHandle(m_pEdges[axis][i].m_handle));
+ }
+ }
+ }
+}
+
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+ Handle* pHandle = static_cast<Handle*>(proxy);
+ aabbMin = pHandle->m_aabbMin;
+ aabbMax = pHandle->m_aabbMax;
}
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+ Handle* pHandle = static_cast<Handle*>(proxy);
+
+ unsigned short vecInMin[3];
+ unsigned short vecInMax[3];
+
+ vecInMin[0] = m_pEdges[0][pHandle->m_minEdges[0]].m_pos ;
+ vecInMax[0] = m_pEdges[0][pHandle->m_maxEdges[0]].m_pos +1 ;
+ vecInMin[1] = m_pEdges[1][pHandle->m_minEdges[1]].m_pos ;
+ vecInMax[1] = m_pEdges[1][pHandle->m_maxEdges[1]].m_pos +1 ;
+ vecInMin[2] = m_pEdges[2][pHandle->m_minEdges[2]].m_pos ;
+ vecInMax[2] = m_pEdges[2][pHandle->m_maxEdges[2]].m_pos +1 ;
+
+ aabbMin.setValue((btScalar)(vecInMin[0]) / (m_quantize.getX()),(btScalar)(vecInMin[1]) / (m_quantize.getY()),(btScalar)(vecInMin[2]) / (m_quantize.getZ()));
+ aabbMin += m_worldAabbMin;
+
+ aabbMax.setValue((btScalar)(vecInMax[0]) / (m_quantize.getX()),(btScalar)(vecInMax[1]) / (m_quantize.getY()),(btScalar)(vecInMax[2]) / (m_quantize.getZ()));
+ aabbMax += m_worldAabbMin;
+}
+
template <typename BP_FP_INT_TYPE>
-btAxisSweep3Internal<BP_FP_INT_TYPE>::btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache )
+btAxisSweep3Internal<BP_FP_INT_TYPE>::btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache , bool disableRaycastAccelerator)
:m_bpHandleMask(handleMask),
m_handleSentinel(handleSentinel),
m_pairCache(pairCache),
m_userPairCallback(0),
m_ownsPairCache(false),
-m_invalidPair(0)
+m_invalidPair(0),
+m_raycastAccelerator(0)
{
BP_FP_INT_TYPE maxHandles = static_cast<BP_FP_INT_TYPE>(userMaxHandles+1);//need to add one sentinel handle
@@ -260,7 +340,14 @@ m_invalidPair(0)
m_ownsPairCache = true;
}
- //assert(bounds.HasVolume());
+ if (!disableRaycastAccelerator)
+ {
+ m_nullPairCache = new (btAlignedAlloc(sizeof(btNullPairCache),16)) btNullPairCache();
+ m_raycastAccelerator = new (btAlignedAlloc(sizeof(btDbvtBroadphase),16)) btDbvtBroadphase(m_nullPairCache);//m_pairCache);
+ m_raycastAccelerator->m_deferedcollide = true;//don't add/remove pairs
+ }
+
+ //btAssert(bounds.HasVolume());
// init bounds
m_worldAabbMin = worldAabbMin;
@@ -320,7 +407,14 @@ m_invalidPair(0)
template <typename BP_FP_INT_TYPE>
btAxisSweep3Internal<BP_FP_INT_TYPE>::~btAxisSweep3Internal()
{
-
+ if (m_raycastAccelerator)
+ {
+ m_nullPairCache->~btOverlappingPairCache();
+ btAlignedFree(m_nullPairCache);
+ m_raycastAccelerator->~btDbvtBroadphase();
+ btAlignedFree (m_raycastAccelerator);
+ }
+
for (int i = 2; i >= 0; i--)
{
btAlignedFree(m_pEdgesRawPtr[i]);
@@ -335,27 +429,31 @@ btAxisSweep3Internal<BP_FP_INT_TYPE>::~btAxisSweep3Internal()
}
template <typename BP_FP_INT_TYPE>
-void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const
{
- btPoint3 clampedPoint(point);
-
-
-
+#ifdef OLD_CLAMPING_METHOD
+ ///problem with this clamping method is that the floating point during quantization might still go outside the range [(0|isMax) .. (m_handleSentinel&m_bpHandleMask]|isMax]
+ ///see http://code.google.com/p/bullet/issues/detail?id=87
+ btVector3 clampedPoint(point);
clampedPoint.setMax(m_worldAabbMin);
clampedPoint.setMin(m_worldAabbMax);
-
btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize;
out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & m_bpHandleMask) | isMax);
out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & m_bpHandleMask) | isMax);
out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & m_bpHandleMask) | isMax);
-
+#else
+ btVector3 v = (point - m_worldAabbMin) * m_quantize;
+ out[0]=(v[0]<=0)?(BP_FP_INT_TYPE)isMax:(v[0]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[0]&m_bpHandleMask)|isMax);
+ out[1]=(v[1]<=0)?(BP_FP_INT_TYPE)isMax:(v[1]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[1]&m_bpHandleMask)|isMax);
+ out[2]=(v[2]<=0)?(BP_FP_INT_TYPE)isMax:(v[2]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[2]&m_bpHandleMask)|isMax);
+#endif //OLD_CLAMPING_METHOD
}
template <typename BP_FP_INT_TYPE>
BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::allocHandle()
{
- assert(m_firstFreeHandle);
+ btAssert(m_firstFreeHandle);
BP_FP_INT_TYPE handle = m_firstFreeHandle;
m_firstFreeHandle = getHandle(handle)->GetNextFree();
@@ -367,7 +465,7 @@ BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::allocHandle()
template <typename BP_FP_INT_TYPE>
void btAxisSweep3Internal<BP_FP_INT_TYPE>::freeHandle(BP_FP_INT_TYPE handle)
{
- assert(handle > 0 && handle < m_maxHandles);
+ btAssert(handle > 0 && handle < m_maxHandles);
getHandle(handle)->SetNextFree(m_firstFreeHandle);
m_firstFreeHandle = handle;
@@ -377,7 +475,7 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::freeHandle(BP_FP_INT_TYPE handle)
template <typename BP_FP_INT_TYPE>
-BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy)
+BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy)
{
// quantize the bounds
BP_FP_INT_TYPE min[3], max[3];
@@ -440,7 +538,7 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::removeHandle(BP_FP_INT_TYPE handle,bt
//explicitly remove the pairs containing the proxy
//we could do it also in the sortMinUp (passing true)
- //todo: compare performance
+ ///@todo: compare performance
if (!m_pairCache->hasDeferredRemoval())
{
m_pairCache->removeOverlappingPairsContainingProxy(pHandle,dispatcher);
@@ -489,6 +587,21 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::removeHandle(BP_FP_INT_TYPE handle,bt
}
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::resetPool(btDispatcher* dispatcher)
+{
+ if (m_numHandles == 0)
+ {
+ m_firstFreeHandle = 1;
+ {
+ for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < m_maxHandles; i++)
+ m_pHandles[i].SetNextFree(static_cast<BP_FP_INT_TYPE>(i + 1));
+ m_pHandles[m_maxHandles - 1].SetNextFree(0);
+ }
+ }
+}
+
+
extern int gOverlappingPairs;
//#include <stdio.h>
@@ -529,6 +642,7 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::calculateOverlappingPairs(btDispatche
if (!isDuplicate)
{
+ ///important to use an AABB test that is consistent with the broadphase
bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
if (hasOverlap)
@@ -574,10 +688,6 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::calculateOverlappingPairs(btDispatche
//printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size());
}
-
-
-
-
}
@@ -616,10 +726,10 @@ bool btAxisSweep3Internal<BP_FP_INT_TYPE>::testOverlap2D(const Handle* pHandleA,
}
template <typename BP_FP_INT_TYPE>
-void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher)
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher)
{
-// assert(bounds.IsFinite());
- //assert(bounds.HasVolume());
+// btAssert(bounds.IsFinite());
+ //btAssert(bounds.HasVolume());
Handle* pHandle = getHandle(handle);
@@ -895,7 +1005,7 @@ class btAxisSweep3 : public btAxisSweep3Internal<unsigned short int>
{
public:
- btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0);
+ btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false);
};
@@ -906,7 +1016,7 @@ class bt32BitAxisSweep3 : public btAxisSweep3Internal<unsigned int>
{
public:
- bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0);
+ bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false);
};
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
index 200ac365329..b7bbaf512ae 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
@@ -21,8 +21,22 @@ subject to the following restrictions:
struct btDispatcherInfo;
class btDispatcher;
#include "btBroadphaseProxy.h"
+
class btOverlappingPairCache;
+
+
+struct btBroadphaseRayCallback
+{
+ ///added some cached data to accelerate ray-AABB tests
+ btVector3 m_rayDirectionInverse;
+ unsigned int m_signs[3];
+ btScalar m_lambda_max;
+
+ virtual ~btBroadphaseRayCallback() {}
+ virtual bool process(const btBroadphaseProxy* proxy) = 0;
+};
+
#include "LinearMath/btVector3.h"
///The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs.
@@ -36,7 +50,10 @@ public:
virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy) =0;
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)=0;
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)=0;
-
+ virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const =0;
+
+ virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)) = 0;
+
///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
virtual void calculateOverlappingPairs(btDispatcher* dispatcher)=0;
@@ -47,6 +64,9 @@ public:
///will add some transform later
virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const =0;
+ ///reset broadphase internal structures, to ensure determinism/reproducability
+ virtual void resetPool(btDispatcher* dispatcher) {};
+
virtual void printStats() = 0;
};
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
index a074a0b150b..be261ec4080 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
@@ -17,20 +17,24 @@ subject to the following restrictions:
#define BROADPHASE_PROXY_H
#include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
+#include "LinearMath/btVector3.h"
#include "LinearMath/btAlignedAllocator.h"
/// btDispatcher uses these types
/// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave
/// to facilitate type checking
+/// CUSTOM_POLYHEDRAL_SHAPE_TYPE,CUSTOM_CONVEX_SHAPE_TYPE and CUSTOM_CONCAVE_SHAPE_TYPE can be used to extend Bullet without modifying source code
enum BroadphaseNativeTypes
{
-// polyhedral convex shapes
+ // polyhedral convex shapes
BOX_SHAPE_PROXYTYPE,
TRIANGLE_SHAPE_PROXYTYPE,
TETRAHEDRAL_SHAPE_PROXYTYPE,
CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE,
CONVEX_HULL_SHAPE_PROXYTYPE,
+ CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE,
+ CUSTOM_POLYHEDRAL_SHAPE_TYPE,
//implicit convex shapes
IMPLICIT_CONVEX_SHAPES_START_HERE,
SPHERE_SHAPE_PROXYTYPE,
@@ -42,6 +46,7 @@ IMPLICIT_CONVEX_SHAPES_START_HERE,
UNIFORM_SCALING_SHAPE_PROXYTYPE,
MINKOWSKI_SUM_SHAPE_PROXYTYPE,
MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,
+ CUSTOM_CONVEX_SHAPE_TYPE,
//concave shapes
CONCAVE_SHAPES_START_HERE,
//keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
@@ -58,13 +63,18 @@ CONCAVE_SHAPES_START_HERE,
EMPTY_SHAPE_PROXYTYPE,
STATIC_PLANE_PROXYTYPE,
+ CUSTOM_CONCAVE_SHAPE_TYPE,
CONCAVE_SHAPES_END_HERE,
COMPOUND_SHAPE_PROXYTYPE,
SOFTBODY_SHAPE_PROXYTYPE,
+ HFFLUID_SHAPE_PROXYTYPE,
+ HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE,
+ INVALID_SHAPE_PROXYTYPE,
MAX_BROADPHASE_COLLISION_TYPES
+
};
@@ -83,20 +93,20 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
KinematicFilter = 4,
DebrisFilter = 8,
SensorTrigger = 16,
+ CharacterFilter = 32,
AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger
};
//Usually the client btCollisionObject or Rigidbody class
void* m_clientObject;
-
short int m_collisionFilterGroup;
short int m_collisionFilterMask;
-
void* m_multiSapParentProxy;
-
-
int m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc.
+ btVector3 m_aabbMin;
+ btVector3 m_aabbMax;
+
SIMD_FORCE_INLINE int getUid() const
{
return m_uniqueId;
@@ -107,10 +117,12 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
{
}
- btBroadphaseProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0)
+ btBroadphaseProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0)
:m_clientObject(userPtr),
m_collisionFilterGroup(collisionFilterGroup),
- m_collisionFilterMask(collisionFilterMask)
+ m_collisionFilterMask(collisionFilterMask),
+ m_aabbMin(aabbMin),
+ m_aabbMax(aabbMax)
{
m_multiSapParentProxy = multiSapParentProxy;
}
@@ -159,7 +171,7 @@ ATTRIBUTE_ALIGNED16(struct) btBroadphasePair
m_pProxy0(0),
m_pProxy1(0),
m_algorithm(0),
- m_userInfo(0)
+ m_internalInfo1(0)
{
}
@@ -169,14 +181,14 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
: m_pProxy0(other.m_pProxy0),
m_pProxy1(other.m_pProxy1),
m_algorithm(other.m_algorithm),
- m_userInfo(other.m_userInfo)
+ m_internalInfo1(other.m_internalInfo1)
{
}
btBroadphasePair(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1)
{
//keep them sorted, so the std::set operations work
- if (&proxy0 < &proxy1)
+ if (proxy0.m_uniqueId < proxy1.m_uniqueId)
{
m_pProxy0 = &proxy0;
m_pProxy1 = &proxy1;
@@ -188,7 +200,7 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
}
m_algorithm = 0;
- m_userInfo = 0;
+ m_internalInfo1 = 0;
}
@@ -196,7 +208,7 @@ BT_DECLARE_ALIGNED_ALLOCATOR();
btBroadphaseProxy* m_pProxy1;
mutable btCollisionAlgorithm* m_algorithm;
- mutable void* m_userInfo;
+ union { void* m_internalInfo1; int m_internalTmpValue;};//don't use this data, it will be removed in future version.
};
@@ -217,8 +229,13 @@ class btBroadphasePairSortPredicate
bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b )
{
- return a.m_pProxy0 > b.m_pProxy0 ||
- (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 > b.m_pProxy1) ||
+ const int uidA0 = a.m_pProxy0 ? a.m_pProxy0->m_uniqueId : -1;
+ const int uidB0 = b.m_pProxy0 ? b.m_pProxy0->m_uniqueId : -1;
+ const int uidA1 = a.m_pProxy1 ? a.m_pProxy1->m_uniqueId : -1;
+ const int uidB1 = b.m_pProxy1 ? b.m_pProxy1->m_uniqueId : -1;
+
+ return uidA0 > uidB0 ||
+ (a.m_pProxy0 == b.m_pProxy0 && uidA1 > uidB1) ||
(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 == b.m_pProxy1 && a.m_algorithm > b.m_algorithm);
}
};
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.cpp
index 7c41c8d8f71..a6e36b47049 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.cpp
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.cpp
@@ -23,188 +23,188 @@ typedef btAlignedObjectArray<const btDbvtNode*> tConstNodeArray;
//
struct btDbvtNodeEnumerator : btDbvt::ICollide
{
-tConstNodeArray nodes;
-void Process(const btDbvtNode* n) { nodes.push_back(n); }
+ tConstNodeArray nodes;
+ void Process(const btDbvtNode* n) { nodes.push_back(n); }
};
//
static DBVT_INLINE int indexof(const btDbvtNode* node)
{
-return(node->parent->childs[1]==node);
+ return(node->parent->childs[1]==node);
}
//
static DBVT_INLINE btDbvtVolume merge( const btDbvtVolume& a,
- const btDbvtVolume& b)
+ const btDbvtVolume& b)
{
-#if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
-DBVT_ALIGN char locals[sizeof(btDbvtAabbMm)];
-btDbvtVolume& res=*(btDbvtVolume*)locals;
+#if (DBVT_MERGE_IMPL==DBVT_IMPL_SSE)
+ ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtAabbMm)]);
+ btDbvtVolume& res=*(btDbvtVolume*)locals;
#else
-btDbvtVolume res;
+ btDbvtVolume res;
#endif
-Merge(a,b,res);
-return(res);
+ Merge(a,b,res);
+ return(res);
}
// volume+edge lengths
static DBVT_INLINE btScalar size(const btDbvtVolume& a)
{
-const btVector3 edges=a.Lengths();
-return( edges.x()*edges.y()*edges.z()+
+ const btVector3 edges=a.Lengths();
+ return( edges.x()*edges.y()*edges.z()+
edges.x()+edges.y()+edges.z());
}
//
static void getmaxdepth(const btDbvtNode* node,int depth,int& maxdepth)
{
-if(node->isinternal())
+ if(node->isinternal())
{
- getmaxdepth(node->childs[0],depth+1,maxdepth);
- getmaxdepth(node->childs[0],depth+1,maxdepth);
+ getmaxdepth(node->childs[0],depth+1,maxdepth);
+ getmaxdepth(node->childs[0],depth+1,maxdepth);
} else maxdepth=btMax(maxdepth,depth);
}
//
static DBVT_INLINE void deletenode( btDbvt* pdbvt,
- btDbvtNode* node)
+ btDbvtNode* node)
{
-btAlignedFree(pdbvt->m_free);
-pdbvt->m_free=node;
+ btAlignedFree(pdbvt->m_free);
+ pdbvt->m_free=node;
}
-
+
//
static void recursedeletenode( btDbvt* pdbvt,
- btDbvtNode* node)
+ btDbvtNode* node)
{
-if(!node->isleaf())
+ if(!node->isleaf())
{
- recursedeletenode(pdbvt,node->childs[0]);
- recursedeletenode(pdbvt,node->childs[1]);
+ recursedeletenode(pdbvt,node->childs[0]);
+ recursedeletenode(pdbvt,node->childs[1]);
}
-if(node==pdbvt->m_root) pdbvt->m_root=0;
-deletenode(pdbvt,node);
+ if(node==pdbvt->m_root) pdbvt->m_root=0;
+ deletenode(pdbvt,node);
}
//
static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt,
- btDbvtNode* parent,
- void* data)
+ btDbvtNode* parent,
+ void* data)
{
-btDbvtNode* node;
-if(pdbvt->m_free)
+ btDbvtNode* node;
+ if(pdbvt->m_free)
{ node=pdbvt->m_free;pdbvt->m_free=0; }
else
{ node=new(btAlignedAlloc(sizeof(btDbvtNode),16)) btDbvtNode(); }
-node->parent = parent;
-node->data = data;
-node->childs[1] = 0;
-return(node);
+ node->parent = parent;
+ node->data = data;
+ node->childs[1] = 0;
+ return(node);
}
//
static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt,
- btDbvtNode* parent,
- const btDbvtVolume& volume,
- void* data)
+ btDbvtNode* parent,
+ const btDbvtVolume& volume,
+ void* data)
{
-btDbvtNode* node=createnode(pdbvt,parent,data);
-node->volume=volume;
-return(node);
+ btDbvtNode* node=createnode(pdbvt,parent,data);
+ node->volume=volume;
+ return(node);
}
//
static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt,
- btDbvtNode* parent,
- const btDbvtVolume& volume0,
- const btDbvtVolume& volume1,
- void* data)
+ btDbvtNode* parent,
+ const btDbvtVolume& volume0,
+ const btDbvtVolume& volume1,
+ void* data)
{
-btDbvtNode* node=createnode(pdbvt,parent,data);
-Merge(volume0,volume1,node->volume);
-return(node);
+ btDbvtNode* node=createnode(pdbvt,parent,data);
+ Merge(volume0,volume1,node->volume);
+ return(node);
}
//
static void insertleaf( btDbvt* pdbvt,
- btDbvtNode* root,
- btDbvtNode* leaf)
+ btDbvtNode* root,
+ btDbvtNode* leaf)
{
-if(!pdbvt->m_root)
+ if(!pdbvt->m_root)
{
- pdbvt->m_root = leaf;
- leaf->parent = 0;
+ pdbvt->m_root = leaf;
+ leaf->parent = 0;
}
else
{
- if(!root->isleaf())
+ if(!root->isleaf())
{
- do {
- root=root->childs[Select( leaf->volume,
- root->childs[0]->volume,
- root->childs[1]->volume)];
+ do {
+ root=root->childs[Select( leaf->volume,
+ root->childs[0]->volume,
+ root->childs[1]->volume)];
} while(!root->isleaf());
}
- btDbvtNode* prev=root->parent;
- btDbvtNode* node=createnode(pdbvt,prev,leaf->volume,root->volume,0);
- if(prev)
+ btDbvtNode* prev=root->parent;
+ btDbvtNode* node=createnode(pdbvt,prev,leaf->volume,root->volume,0);
+ if(prev)
{
- prev->childs[indexof(root)] = node;
- node->childs[0] = root;root->parent=node;
- node->childs[1] = leaf;leaf->parent=node;
- do {
- if(!prev->volume.Contain(node->volume))
- Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
+ prev->childs[indexof(root)] = node;
+ node->childs[0] = root;root->parent=node;
+ node->childs[1] = leaf;leaf->parent=node;
+ do {
+ if(!prev->volume.Contain(node->volume))
+ Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
else
- break;
- node=prev;
+ break;
+ node=prev;
} while(0!=(prev=node->parent));
}
else
{
- node->childs[0] = root;root->parent=node;
- node->childs[1] = leaf;leaf->parent=node;
- pdbvt->m_root = node;
+ node->childs[0] = root;root->parent=node;
+ node->childs[1] = leaf;leaf->parent=node;
+ pdbvt->m_root = node;
}
}
}
-
+
//
static btDbvtNode* removeleaf( btDbvt* pdbvt,
- btDbvtNode* leaf)
+ btDbvtNode* leaf)
{
-if(leaf==pdbvt->m_root)
+ if(leaf==pdbvt->m_root)
{
- pdbvt->m_root=0;
- return(0);
+ pdbvt->m_root=0;
+ return(0);
}
else
{
- btDbvtNode* parent=leaf->parent;
- btDbvtNode* prev=parent->parent;
- btDbvtNode* sibling=parent->childs[1-indexof(leaf)];
- if(prev)
+ btDbvtNode* parent=leaf->parent;
+ btDbvtNode* prev=parent->parent;
+ btDbvtNode* sibling=parent->childs[1-indexof(leaf)];
+ if(prev)
{
- prev->childs[indexof(parent)]=sibling;
- sibling->parent=prev;
- deletenode(pdbvt,parent);
- while(prev)
+ prev->childs[indexof(parent)]=sibling;
+ sibling->parent=prev;
+ deletenode(pdbvt,parent);
+ while(prev)
{
- const btDbvtVolume pb=prev->volume;
- Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
- if(NotEqual(pb,prev->volume))
+ const btDbvtVolume pb=prev->volume;
+ Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
+ if(NotEqual(pb,prev->volume))
{
- prev=prev->parent;
+ prev=prev->parent;
} else break;
}
- return(prev?prev:pdbvt->m_root);
+ return(prev?prev:pdbvt->m_root);
}
else
{
- pdbvt->m_root=sibling;
- sibling->parent=0;
- deletenode(pdbvt,parent);
- return(pdbvt->m_root);
+ pdbvt->m_root=sibling;
+ sibling->parent=0;
+ deletenode(pdbvt,parent);
+ return(pdbvt->m_root);
}
}
}
@@ -215,33 +215,33 @@ static void fetchleaves(btDbvt* pdbvt,
tNodeArray& leaves,
int depth=-1)
{
-if(root->isinternal()&&depth)
+ if(root->isinternal()&&depth)
{
- fetchleaves(pdbvt,root->childs[0],leaves,depth-1);
- fetchleaves(pdbvt,root->childs[1],leaves,depth-1);
- deletenode(pdbvt,root);
+ fetchleaves(pdbvt,root->childs[0],leaves,depth-1);
+ fetchleaves(pdbvt,root->childs[1],leaves,depth-1);
+ deletenode(pdbvt,root);
}
else
{
- leaves.push_back(root);
+ leaves.push_back(root);
}
}
//
static void split( const tNodeArray& leaves,
- tNodeArray& left,
- tNodeArray& right,
- const btVector3& org,
- const btVector3& axis)
+ tNodeArray& left,
+ tNodeArray& right,
+ const btVector3& org,
+ const btVector3& axis)
{
-left.resize(0);
-right.resize(0);
-for(int i=0,ni=leaves.size();i<ni;++i)
+ left.resize(0);
+ right.resize(0);
+ for(int i=0,ni=leaves.size();i<ni;++i)
{
- if(dot(axis,leaves[i]->volume.Center()-org)<0)
- left.push_back(leaves[i]);
+ if(dot(axis,leaves[i]->volume.Center()-org)<0)
+ left.push_back(leaves[i]);
else
- right.push_back(leaves[i]);
+ right.push_back(leaves[i]);
}
}
@@ -249,49 +249,49 @@ for(int i=0,ni=leaves.size();i<ni;++i)
static btDbvtVolume bounds( const tNodeArray& leaves)
{
#if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
-DBVT_ALIGN char locals[sizeof(btDbvtVolume)];
-btDbvtVolume& volume=*(btDbvtVolume*)locals;
-volume=leaves[0]->volume;
+ ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtVolume)]);
+ btDbvtVolume& volume=*(btDbvtVolume*)locals;
+ volume=leaves[0]->volume;
#else
-btDbvtVolume volume=leaves[0]->volume;
+ btDbvtVolume volume=leaves[0]->volume;
#endif
-for(int i=1,ni=leaves.size();i<ni;++i)
+ for(int i=1,ni=leaves.size();i<ni;++i)
{
- Merge(volume,leaves[i]->volume,volume);
+ Merge(volume,leaves[i]->volume,volume);
}
-return(volume);
+ return(volume);
}
//
static void bottomup( btDbvt* pdbvt,
- tNodeArray& leaves)
+ tNodeArray& leaves)
{
-while(leaves.size()>1)
+ while(leaves.size()>1)
{
- btScalar minsize=SIMD_INFINITY;
- int minidx[2]={-1,-1};
- for(int i=0;i<leaves.size();++i)
+ btScalar minsize=SIMD_INFINITY;
+ int minidx[2]={-1,-1};
+ for(int i=0;i<leaves.size();++i)
{
- for(int j=i+1;j<leaves.size();++j)
+ for(int j=i+1;j<leaves.size();++j)
{
- const btScalar sz=size(merge(leaves[i]->volume,leaves[j]->volume));
- if(sz<minsize)
+ const btScalar sz=size(merge(leaves[i]->volume,leaves[j]->volume));
+ if(sz<minsize)
{
- minsize = sz;
- minidx[0] = i;
- minidx[1] = j;
+ minsize = sz;
+ minidx[0] = i;
+ minidx[1] = j;
}
}
}
- btDbvtNode* n[] = {leaves[minidx[0]],leaves[minidx[1]]};
- btDbvtNode* p = createnode(pdbvt,0,n[0]->volume,n[1]->volume,0);
- p->childs[0] = n[0];
- p->childs[1] = n[1];
- n[0]->parent = p;
- n[1]->parent = p;
- leaves[minidx[0]] = p;
- leaves.swap(minidx[1],leaves.size()-1);
- leaves.pop_back();
+ btDbvtNode* n[] = {leaves[minidx[0]],leaves[minidx[1]]};
+ btDbvtNode* p = createnode(pdbvt,0,n[0]->volume,n[1]->volume,0);
+ p->childs[0] = n[0];
+ p->childs[1] = n[1];
+ n[0]->parent = p;
+ n[1]->parent = p;
+ leaves[minidx[0]] = p;
+ leaves.swap(minidx[1],leaves.size()-1);
+ leaves.pop_back();
}
}
@@ -300,175 +300,181 @@ static btDbvtNode* topdown(btDbvt* pdbvt,
tNodeArray& leaves,
int bu_treshold)
{
-static const btVector3 axis[]={btVector3(1,0,0),
- btVector3(0,1,0),
- btVector3(0,0,1)};
-if(leaves.size()>1)
+ static const btVector3 axis[]={btVector3(1,0,0),
+ btVector3(0,1,0),
+ btVector3(0,0,1)};
+ if(leaves.size()>1)
{
- if(leaves.size()>bu_treshold)
+ if(leaves.size()>bu_treshold)
{
- const btDbvtVolume vol=bounds(leaves);
- const btVector3 org=vol.Center();
- tNodeArray sets[2];
- int bestaxis=-1;
- int bestmidp=leaves.size();
- int splitcount[3][2]={{0,0},{0,0},{0,0}};
- int i;
- for( i=0;i<leaves.size();++i)
+ const btDbvtVolume vol=bounds(leaves);
+ const btVector3 org=vol.Center();
+ tNodeArray sets[2];
+ int bestaxis=-1;
+ int bestmidp=leaves.size();
+ int splitcount[3][2]={{0,0},{0,0},{0,0}};
+ int i;
+ for( i=0;i<leaves.size();++i)
{
- const btVector3 x=leaves[i]->volume.Center()-org;
- for(int j=0;j<3;++j)
+ const btVector3 x=leaves[i]->volume.Center()-org;
+ for(int j=0;j<3;++j)
{
- ++splitcount[j][dot(x,axis[j])>0?1:0];
+ ++splitcount[j][dot(x,axis[j])>0?1:0];
}
}
- for( i=0;i<3;++i)
+ for( i=0;i<3;++i)
{
- if((splitcount[i][0]>0)&&(splitcount[i][1]>0))
+ if((splitcount[i][0]>0)&&(splitcount[i][1]>0))
{
- const int midp=(int)btFabs(btScalar(splitcount[i][0]-splitcount[i][1]));
- if(midp<bestmidp)
+ const int midp=(int)btFabs(btScalar(splitcount[i][0]-splitcount[i][1]));
+ if(midp<bestmidp)
{
- bestaxis=i;
- bestmidp=midp;
+ bestaxis=i;
+ bestmidp=midp;
}
}
}
- if(bestaxis>=0)
+ if(bestaxis>=0)
{
- sets[0].reserve(splitcount[bestaxis][0]);
- sets[1].reserve(splitcount[bestaxis][1]);
- split(leaves,sets[0],sets[1],org,axis[bestaxis]);
+ sets[0].reserve(splitcount[bestaxis][0]);
+ sets[1].reserve(splitcount[bestaxis][1]);
+ split(leaves,sets[0],sets[1],org,axis[bestaxis]);
}
else
{
- sets[0].reserve(leaves.size()/2+1);
- sets[1].reserve(leaves.size()/2);
- for(int i=0,ni=leaves.size();i<ni;++i)
+ sets[0].reserve(leaves.size()/2+1);
+ sets[1].reserve(leaves.size()/2);
+ for(int i=0,ni=leaves.size();i<ni;++i)
{
- sets[i&1].push_back(leaves[i]);
+ sets[i&1].push_back(leaves[i]);
}
}
- btDbvtNode* node=createnode(pdbvt,0,vol,0);
- node->childs[0]=topdown(pdbvt,sets[0],bu_treshold);
- node->childs[1]=topdown(pdbvt,sets[1],bu_treshold);
- node->childs[0]->parent=node;
- node->childs[1]->parent=node;
- return(node);
+ btDbvtNode* node=createnode(pdbvt,0,vol,0);
+ node->childs[0]=topdown(pdbvt,sets[0],bu_treshold);
+ node->childs[1]=topdown(pdbvt,sets[1],bu_treshold);
+ node->childs[0]->parent=node;
+ node->childs[1]->parent=node;
+ return(node);
}
else
{
- bottomup(pdbvt,leaves);
- return(leaves[0]);
+ bottomup(pdbvt,leaves);
+ return(leaves[0]);
}
}
-return(leaves[0]);
+ return(leaves[0]);
}
//
static DBVT_INLINE btDbvtNode* sort(btDbvtNode* n,btDbvtNode*& r)
{
-btDbvtNode* p=n->parent;
-btAssert(n->isinternal());
-if(p>n)
+ btDbvtNode* p=n->parent;
+ btAssert(n->isinternal());
+ if(p>n)
{
- const int i=indexof(n);
- const int j=1-i;
- btDbvtNode* s=p->childs[j];
- btDbvtNode* q=p->parent;
- btAssert(n==p->childs[i]);
- if(q) q->childs[indexof(p)]=n; else r=n;
- s->parent=n;
- p->parent=n;
- n->parent=q;
- p->childs[0]=n->childs[0];
- p->childs[1]=n->childs[1];
- n->childs[0]->parent=p;
- n->childs[1]->parent=p;
- n->childs[i]=p;
- n->childs[j]=s;
- btSwap(p->volume,n->volume);
- return(p);
+ const int i=indexof(n);
+ const int j=1-i;
+ btDbvtNode* s=p->childs[j];
+ btDbvtNode* q=p->parent;
+ btAssert(n==p->childs[i]);
+ if(q) q->childs[indexof(p)]=n; else r=n;
+ s->parent=n;
+ p->parent=n;
+ n->parent=q;
+ p->childs[0]=n->childs[0];
+ p->childs[1]=n->childs[1];
+ n->childs[0]->parent=p;
+ n->childs[1]->parent=p;
+ n->childs[i]=p;
+ n->childs[j]=s;
+ btSwap(p->volume,n->volume);
+ return(p);
}
-return(n);
+ return(n);
}
-//
+#if 0
static DBVT_INLINE btDbvtNode* walkup(btDbvtNode* n,int count)
{
-while(n&&(count--)) n=n->parent;
-return(n);
+ while(n&&(count--)) n=n->parent;
+ return(n);
}
+#endif
//
// Api
//
//
- btDbvt::btDbvt()
+btDbvt::btDbvt()
{
-m_root = 0;
-m_free = 0;
-m_lkhd = -1;
-m_leaves = 0;
-m_opath = 0;
+ m_root = 0;
+ m_free = 0;
+ m_lkhd = -1;
+ m_leaves = 0;
+ m_opath = 0;
}
//
- btDbvt::~btDbvt()
+btDbvt::~btDbvt()
{
-clear();
+ clear();
}
//
void btDbvt::clear()
{
-if(m_root) recursedeletenode(this,m_root);
-btAlignedFree(m_free);
-m_free=0;
+ if(m_root)
+ recursedeletenode(this,m_root);
+ btAlignedFree(m_free);
+ m_free=0;
+ m_lkhd = -1;
+ m_stkStack.clear();
+ m_opath = 0;
+
}
//
void btDbvt::optimizeBottomUp()
{
-if(m_root)
+ if(m_root)
{
- tNodeArray leaves;
- leaves.reserve(m_leaves);
- fetchleaves(this,m_root,leaves);
- bottomup(this,leaves);
- m_root=leaves[0];
+ tNodeArray leaves;
+ leaves.reserve(m_leaves);
+ fetchleaves(this,m_root,leaves);
+ bottomup(this,leaves);
+ m_root=leaves[0];
}
}
//
void btDbvt::optimizeTopDown(int bu_treshold)
{
-if(m_root)
+ if(m_root)
{
- tNodeArray leaves;
- leaves.reserve(m_leaves);
- fetchleaves(this,m_root,leaves);
- m_root=topdown(this,leaves,bu_treshold);
+ tNodeArray leaves;
+ leaves.reserve(m_leaves);
+ fetchleaves(this,m_root,leaves);
+ m_root=topdown(this,leaves,bu_treshold);
}
}
//
void btDbvt::optimizeIncremental(int passes)
{
-if(passes<0) passes=m_leaves;
-if(m_root&&(passes>0))
+ if(passes<0) passes=m_leaves;
+ if(m_root&&(passes>0))
{
- do {
- btDbvtNode* node=m_root;
- unsigned bit=0;
- while(node->isinternal())
+ do {
+ btDbvtNode* node=m_root;
+ unsigned bit=0;
+ while(node->isinternal())
{
- node=sort(node,m_root)->childs[(m_opath>>bit)&1];
- bit=(bit+1)&(sizeof(unsigned)*8-1);
+ node=sort(node,m_root)->childs[(m_opath>>bit)&1];
+ bit=(bit+1)&(sizeof(unsigned)*8-1);
}
- update(node);
- ++m_opath;
+ update(node);
+ ++m_opath;
} while(--passes);
}
}
@@ -476,104 +482,104 @@ if(m_root&&(passes>0))
//
btDbvtNode* btDbvt::insert(const btDbvtVolume& volume,void* data)
{
-btDbvtNode* leaf=createnode(this,0,volume,data);
-insertleaf(this,m_root,leaf);
-++m_leaves;
-return(leaf);
+ btDbvtNode* leaf=createnode(this,0,volume,data);
+ insertleaf(this,m_root,leaf);
+ ++m_leaves;
+ return(leaf);
}
//
void btDbvt::update(btDbvtNode* leaf,int lookahead)
{
-btDbvtNode* root=removeleaf(this,leaf);
-if(root)
+ btDbvtNode* root=removeleaf(this,leaf);
+ if(root)
{
- if(lookahead>=0)
+ if(lookahead>=0)
{
- for(int i=0;(i<lookahead)&&root->parent;++i)
+ for(int i=0;(i<lookahead)&&root->parent;++i)
{
- root=root->parent;
+ root=root->parent;
}
} else root=m_root;
}
-insertleaf(this,root,leaf);
+ insertleaf(this,root,leaf);
}
//
-void btDbvt::update(btDbvtNode* leaf,const btDbvtVolume& volume)
+void btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume)
{
-btDbvtNode* root=removeleaf(this,leaf);
-if(root)
+ btDbvtNode* root=removeleaf(this,leaf);
+ if(root)
{
- if(m_lkhd>=0)
+ if(m_lkhd>=0)
{
- for(int i=0;(i<m_lkhd)&&root->parent;++i)
+ for(int i=0;(i<m_lkhd)&&root->parent;++i)
{
- root=root->parent;
+ root=root->parent;
}
} else root=m_root;
}
-leaf->volume=volume;
-insertleaf(this,root,leaf);
+ leaf->volume=volume;
+ insertleaf(this,root,leaf);
}
//
-bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity,btScalar margin)
+bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin)
{
-if(leaf->volume.Contain(volume)) return(false);
-volume.Expand(btVector3(margin,margin,margin));
-volume.SignedExpand(velocity);
-update(leaf,volume);
-return(true);
+ if(leaf->volume.Contain(volume)) return(false);
+ volume.Expand(btVector3(margin,margin,margin));
+ volume.SignedExpand(velocity);
+ update(leaf,volume);
+ return(true);
}
//
-bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity)
+bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity)
{
-if(leaf->volume.Contain(volume)) return(false);
-volume.SignedExpand(velocity);
-update(leaf,volume);
-return(true);
+ if(leaf->volume.Contain(volume)) return(false);
+ volume.SignedExpand(velocity);
+ update(leaf,volume);
+ return(true);
}
//
-bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume volume,btScalar margin)
+bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin)
{
-if(leaf->volume.Contain(volume)) return(false);
-volume.Expand(btVector3(margin,margin,margin));
-update(leaf,volume);
-return(true);
+ if(leaf->volume.Contain(volume)) return(false);
+ volume.Expand(btVector3(margin,margin,margin));
+ update(leaf,volume);
+ return(true);
}
//
void btDbvt::remove(btDbvtNode* leaf)
{
-removeleaf(this,leaf);
-deletenode(this,leaf);
---m_leaves;
+ removeleaf(this,leaf);
+ deletenode(this,leaf);
+ --m_leaves;
}
//
void btDbvt::write(IWriter* iwriter) const
{
-btDbvtNodeEnumerator nodes;
-nodes.nodes.reserve(m_leaves*2);
-enumNodes(m_root,nodes);
-iwriter->Prepare(m_root,nodes.nodes.size());
-for(int i=0;i<nodes.nodes.size();++i)
+ btDbvtNodeEnumerator nodes;
+ nodes.nodes.reserve(m_leaves*2);
+ enumNodes(m_root,nodes);
+ iwriter->Prepare(m_root,nodes.nodes.size());
+ for(int i=0;i<nodes.nodes.size();++i)
{
- const btDbvtNode* n=nodes.nodes[i];
- int p=-1;
- if(n->parent) p=nodes.nodes.findLinearSearch(n->parent);
- if(n->isinternal())
+ const btDbvtNode* n=nodes.nodes[i];
+ int p=-1;
+ if(n->parent) p=nodes.nodes.findLinearSearch(n->parent);
+ if(n->isinternal())
{
- const int c0=nodes.nodes.findLinearSearch(n->childs[0]);
- const int c1=nodes.nodes.findLinearSearch(n->childs[1]);
- iwriter->WriteNode(n,i,p,c0,c1);
+ const int c0=nodes.nodes.findLinearSearch(n->childs[0]);
+ const int c1=nodes.nodes.findLinearSearch(n->childs[1]);
+ iwriter->WriteNode(n,i,p,c0,c1);
}
else
{
- iwriter->WriteLeaf(n,i,p);
+ iwriter->WriteLeaf(n,i,p);
}
}
}
@@ -581,29 +587,29 @@ for(int i=0;i<nodes.nodes.size();++i)
//
void btDbvt::clone(btDbvt& dest,IClone* iclone) const
{
-dest.clear();
-if(m_root!=0)
+ dest.clear();
+ if(m_root!=0)
{
- btAlignedObjectArray<sStkCLN> stack;
- stack.reserve(m_leaves);
- stack.push_back(sStkCLN(m_root,0));
- do {
- const int i=stack.size()-1;
- const sStkCLN e=stack[i];
- btDbvtNode* n=createnode(&dest,e.parent,e.node->volume,e.node->data);
- stack.pop_back();
- if(e.parent!=0)
- e.parent->childs[i&1]=n;
+ btAlignedObjectArray<sStkCLN> stack;
+ stack.reserve(m_leaves);
+ stack.push_back(sStkCLN(m_root,0));
+ do {
+ const int i=stack.size()-1;
+ const sStkCLN e=stack[i];
+ btDbvtNode* n=createnode(&dest,e.parent,e.node->volume,e.node->data);
+ stack.pop_back();
+ if(e.parent!=0)
+ e.parent->childs[i&1]=n;
else
- dest.m_root=n;
- if(e.node->isinternal())
+ dest.m_root=n;
+ if(e.node->isinternal())
{
- stack.push_back(sStkCLN(e.node->childs[0],n));
- stack.push_back(sStkCLN(e.node->childs[1],n));
+ stack.push_back(sStkCLN(e.node->childs[0],n));
+ stack.push_back(sStkCLN(e.node->childs[1],n));
}
else
{
- iclone->CloneLeaf(n);
+ iclone->CloneLeaf(n);
}
} while(stack.size()>0);
}
@@ -612,31 +618,31 @@ if(m_root!=0)
//
int btDbvt::maxdepth(const btDbvtNode* node)
{
-int depth=0;
-if(node) getmaxdepth(node,1,depth);
-return(depth);
+ int depth=0;
+ if(node) getmaxdepth(node,1,depth);
+ return(depth);
}
//
int btDbvt::countLeaves(const btDbvtNode* node)
{
-if(node->isinternal())
- return(countLeaves(node->childs[0])+countLeaves(node->childs[1]));
+ if(node->isinternal())
+ return(countLeaves(node->childs[0])+countLeaves(node->childs[1]));
else
- return(1);
+ return(1);
}
//
void btDbvt::extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves)
{
-if(node->isinternal())
+ if(node->isinternal())
{
- extractLeaves(node->childs[0],leaves);
- extractLeaves(node->childs[1],leaves);
+ extractLeaves(node->childs[0],leaves);
+ extractLeaves(node->childs[1],leaves);
}
else
{
- leaves.push_back(node);
+ leaves.push_back(node);
}
}
@@ -657,19 +663,19 @@ q6600,2.4ghz
/W3 /nologo /c /Wp64 /Zi /errorReport:prompt
Benchmarking dbvt...
- World scale: 100.000000
- Extents base: 1.000000
- Extents range: 4.000000
- Leaves: 8192
- sizeof(btDbvtVolume): 32 bytes
- sizeof(btDbvtNode): 44 bytes
+World scale: 100.000000
+Extents base: 1.000000
+Extents range: 4.000000
+Leaves: 8192
+sizeof(btDbvtVolume): 32 bytes
+sizeof(btDbvtNode): 44 bytes
[1] btDbvtVolume intersections: 3499 ms (-1%)
[2] btDbvtVolume merges: 1934 ms (0%)
[3] btDbvt::collideTT: 5485 ms (-21%)
[4] btDbvt::collideTT self: 2814 ms (-20%)
[5] btDbvt::collideTT xform: 7379 ms (-1%)
[6] btDbvt::collideTT xform,self: 7270 ms (-2%)
-[7] btDbvt::collideRAY: 6314 ms (0%),(332143 r/s)
+[7] btDbvt::rayTest: 6314 ms (0%),(332143 r/s)
[8] insert/remove: 2093 ms (0%),(1001983 ir/s)
[9] updates (teleport): 1879 ms (-3%),(1116100 u/s)
[10] updates (jitter): 1244 ms (-4%),(1685813 u/s)
@@ -684,606 +690,606 @@ Benchmarking dbvt...
struct btDbvtBenchmark
{
-struct NilPolicy : btDbvt::ICollide
+ struct NilPolicy : btDbvt::ICollide
{
- NilPolicy() : m_pcount(0),m_depth(-SIMD_INFINITY),m_checksort(true) {}
- void Process(const btDbvtNode*,const btDbvtNode*) { ++m_pcount; }
- void Process(const btDbvtNode*) { ++m_pcount; }
- void Process(const btDbvtNode*,btScalar depth)
+ NilPolicy() : m_pcount(0),m_depth(-SIMD_INFINITY),m_checksort(true) {}
+ void Process(const btDbvtNode*,const btDbvtNode*) { ++m_pcount; }
+ void Process(const btDbvtNode*) { ++m_pcount; }
+ void Process(const btDbvtNode*,btScalar depth)
{
- ++m_pcount;
- if(m_checksort)
+ ++m_pcount;
+ if(m_checksort)
{ if(depth>=m_depth) m_depth=depth; else printf("wrong depth: %f (should be >= %f)\r\n",depth,m_depth); }
}
- int m_pcount;
- btScalar m_depth;
- bool m_checksort;
+ int m_pcount;
+ btScalar m_depth;
+ bool m_checksort;
};
-struct P14 : btDbvt::ICollide
+ struct P14 : btDbvt::ICollide
{
- struct Node
+ struct Node
{
- const btDbvtNode* leaf;
- btScalar depth;
+ const btDbvtNode* leaf;
+ btScalar depth;
};
- void Process(const btDbvtNode* leaf,btScalar depth)
+ void Process(const btDbvtNode* leaf,btScalar depth)
{
- Node n;
- n.leaf = leaf;
- n.depth = depth;
+ Node n;
+ n.leaf = leaf;
+ n.depth = depth;
}
- static int sortfnc(const Node& a,const Node& b)
+ static int sortfnc(const Node& a,const Node& b)
{
- if(a.depth<b.depth) return(+1);
- if(a.depth>b.depth) return(-1);
- return(0);
+ if(a.depth<b.depth) return(+1);
+ if(a.depth>b.depth) return(-1);
+ return(0);
}
- btAlignedObjectArray<Node> m_nodes;
+ btAlignedObjectArray<Node> m_nodes;
};
-struct P15 : btDbvt::ICollide
+ struct P15 : btDbvt::ICollide
{
- struct Node
+ struct Node
{
- const btDbvtNode* leaf;
- btScalar depth;
+ const btDbvtNode* leaf;
+ btScalar depth;
};
- void Process(const btDbvtNode* leaf)
+ void Process(const btDbvtNode* leaf)
{
- Node n;
- n.leaf = leaf;
- n.depth = dot(leaf->volume.Center(),m_axis);
+ Node n;
+ n.leaf = leaf;
+ n.depth = dot(leaf->volume.Center(),m_axis);
}
- static int sortfnc(const Node& a,const Node& b)
+ static int sortfnc(const Node& a,const Node& b)
{
- if(a.depth<b.depth) return(+1);
- if(a.depth>b.depth) return(-1);
- return(0);
+ if(a.depth<b.depth) return(+1);
+ if(a.depth>b.depth) return(-1);
+ return(0);
}
- btAlignedObjectArray<Node> m_nodes;
- btVector3 m_axis;
+ btAlignedObjectArray<Node> m_nodes;
+ btVector3 m_axis;
};
-static btScalar RandUnit()
+ static btScalar RandUnit()
{
- return(rand()/(btScalar)RAND_MAX);
+ return(rand()/(btScalar)RAND_MAX);
}
-static btVector3 RandVector3()
+ static btVector3 RandVector3()
{
- return(btVector3(RandUnit(),RandUnit(),RandUnit()));
+ return(btVector3(RandUnit(),RandUnit(),RandUnit()));
}
-static btVector3 RandVector3(btScalar cs)
+ static btVector3 RandVector3(btScalar cs)
{
- return(RandVector3()*cs-btVector3(cs,cs,cs)/2);
+ return(RandVector3()*cs-btVector3(cs,cs,cs)/2);
}
-static btDbvtVolume RandVolume(btScalar cs,btScalar eb,btScalar es)
+ static btDbvtVolume RandVolume(btScalar cs,btScalar eb,btScalar es)
{
- return(btDbvtVolume::FromCE(RandVector3(cs),btVector3(eb,eb,eb)+RandVector3()*es));
+ return(btDbvtVolume::FromCE(RandVector3(cs),btVector3(eb,eb,eb)+RandVector3()*es));
}
-static btTransform RandTransform(btScalar cs)
+ static btTransform RandTransform(btScalar cs)
{
- btTransform t;
- t.setOrigin(RandVector3(cs));
- t.setRotation(btQuaternion(RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2).normalized());
- return(t);
+ btTransform t;
+ t.setOrigin(RandVector3(cs));
+ t.setRotation(btQuaternion(RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2).normalized());
+ return(t);
}
-static void RandTree(btScalar cs,btScalar eb,btScalar es,int leaves,btDbvt& dbvt)
+ static void RandTree(btScalar cs,btScalar eb,btScalar es,int leaves,btDbvt& dbvt)
{
- dbvt.clear();
- for(int i=0;i<leaves;++i)
+ dbvt.clear();
+ for(int i=0;i<leaves;++i)
{
- dbvt.insert(RandVolume(cs,eb,es),0);
+ dbvt.insert(RandVolume(cs,eb,es),0);
}
}
};
void btDbvt::benchmark()
{
-static const btScalar cfgVolumeCenterScale = 100;
-static const btScalar cfgVolumeExentsBase = 1;
-static const btScalar cfgVolumeExentsScale = 4;
-static const int cfgLeaves = 8192;
-static const bool cfgEnable = true;
+ static const btScalar cfgVolumeCenterScale = 100;
+ static const btScalar cfgVolumeExentsBase = 1;
+ static const btScalar cfgVolumeExentsScale = 4;
+ static const int cfgLeaves = 8192;
+ static const bool cfgEnable = true;
-//[1] btDbvtVolume intersections
-bool cfgBenchmark1_Enable = cfgEnable;
-static const int cfgBenchmark1_Iterations = 8;
-static const int cfgBenchmark1_Reference = 3499;
-//[2] btDbvtVolume merges
-bool cfgBenchmark2_Enable = cfgEnable;
-static const int cfgBenchmark2_Iterations = 4;
-static const int cfgBenchmark2_Reference = 1945;
-//[3] btDbvt::collideTT
-bool cfgBenchmark3_Enable = cfgEnable;
-static const int cfgBenchmark3_Iterations = 512;
-static const int cfgBenchmark3_Reference = 5485;
-//[4] btDbvt::collideTT self
-bool cfgBenchmark4_Enable = cfgEnable;
-static const int cfgBenchmark4_Iterations = 512;
-static const int cfgBenchmark4_Reference = 2814;
-//[5] btDbvt::collideTT xform
-bool cfgBenchmark5_Enable = cfgEnable;
-static const int cfgBenchmark5_Iterations = 512;
-static const btScalar cfgBenchmark5_OffsetScale = 2;
-static const int cfgBenchmark5_Reference = 7379;
-//[6] btDbvt::collideTT xform,self
-bool cfgBenchmark6_Enable = cfgEnable;
-static const int cfgBenchmark6_Iterations = 512;
-static const btScalar cfgBenchmark6_OffsetScale = 2;
-static const int cfgBenchmark6_Reference = 7270;
-//[7] btDbvt::collideRAY
-bool cfgBenchmark7_Enable = cfgEnable;
-static const int cfgBenchmark7_Passes = 32;
-static const int cfgBenchmark7_Iterations = 65536;
-static const int cfgBenchmark7_Reference = 6307;
-//[8] insert/remove
-bool cfgBenchmark8_Enable = cfgEnable;
-static const int cfgBenchmark8_Passes = 32;
-static const int cfgBenchmark8_Iterations = 65536;
-static const int cfgBenchmark8_Reference = 2105;
-//[9] updates (teleport)
-bool cfgBenchmark9_Enable = cfgEnable;
-static const int cfgBenchmark9_Passes = 32;
-static const int cfgBenchmark9_Iterations = 65536;
-static const int cfgBenchmark9_Reference = 1879;
-//[10] updates (jitter)
-bool cfgBenchmark10_Enable = cfgEnable;
-static const btScalar cfgBenchmark10_Scale = cfgVolumeCenterScale/10000;
-static const int cfgBenchmark10_Passes = 32;
-static const int cfgBenchmark10_Iterations = 65536;
-static const int cfgBenchmark10_Reference = 1244;
-//[11] optimize (incremental)
-bool cfgBenchmark11_Enable = cfgEnable;
-static const int cfgBenchmark11_Passes = 64;
-static const int cfgBenchmark11_Iterations = 65536;
-static const int cfgBenchmark11_Reference = 2510;
-//[12] btDbvtVolume notequal
-bool cfgBenchmark12_Enable = cfgEnable;
-static const int cfgBenchmark12_Iterations = 32;
-static const int cfgBenchmark12_Reference = 3677;
-//[13] culling(OCL+fullsort)
-bool cfgBenchmark13_Enable = cfgEnable;
-static const int cfgBenchmark13_Iterations = 1024;
-static const int cfgBenchmark13_Reference = 2231;
-//[14] culling(OCL+qsort)
-bool cfgBenchmark14_Enable = cfgEnable;
-static const int cfgBenchmark14_Iterations = 8192;
-static const int cfgBenchmark14_Reference = 3500;
-//[15] culling(KDOP+qsort)
-bool cfgBenchmark15_Enable = cfgEnable;
-static const int cfgBenchmark15_Iterations = 8192;
-static const int cfgBenchmark15_Reference = 1151;
-//[16] insert/remove batch
-bool cfgBenchmark16_Enable = cfgEnable;
-static const int cfgBenchmark16_BatchCount = 256;
-static const int cfgBenchmark16_Passes = 16384;
-static const int cfgBenchmark16_Reference = 5138;
-//[17] select
-bool cfgBenchmark17_Enable = cfgEnable;
-static const int cfgBenchmark17_Iterations = 4;
-static const int cfgBenchmark17_Reference = 3390;
+ //[1] btDbvtVolume intersections
+ bool cfgBenchmark1_Enable = cfgEnable;
+ static const int cfgBenchmark1_Iterations = 8;
+ static const int cfgBenchmark1_Reference = 3499;
+ //[2] btDbvtVolume merges
+ bool cfgBenchmark2_Enable = cfgEnable;
+ static const int cfgBenchmark2_Iterations = 4;
+ static const int cfgBenchmark2_Reference = 1945;
+ //[3] btDbvt::collideTT
+ bool cfgBenchmark3_Enable = cfgEnable;
+ static const int cfgBenchmark3_Iterations = 512;
+ static const int cfgBenchmark3_Reference = 5485;
+ //[4] btDbvt::collideTT self
+ bool cfgBenchmark4_Enable = cfgEnable;
+ static const int cfgBenchmark4_Iterations = 512;
+ static const int cfgBenchmark4_Reference = 2814;
+ //[5] btDbvt::collideTT xform
+ bool cfgBenchmark5_Enable = cfgEnable;
+ static const int cfgBenchmark5_Iterations = 512;
+ static const btScalar cfgBenchmark5_OffsetScale = 2;
+ static const int cfgBenchmark5_Reference = 7379;
+ //[6] btDbvt::collideTT xform,self
+ bool cfgBenchmark6_Enable = cfgEnable;
+ static const int cfgBenchmark6_Iterations = 512;
+ static const btScalar cfgBenchmark6_OffsetScale = 2;
+ static const int cfgBenchmark6_Reference = 7270;
+ //[7] btDbvt::rayTest
+ bool cfgBenchmark7_Enable = cfgEnable;
+ static const int cfgBenchmark7_Passes = 32;
+ static const int cfgBenchmark7_Iterations = 65536;
+ static const int cfgBenchmark7_Reference = 6307;
+ //[8] insert/remove
+ bool cfgBenchmark8_Enable = cfgEnable;
+ static const int cfgBenchmark8_Passes = 32;
+ static const int cfgBenchmark8_Iterations = 65536;
+ static const int cfgBenchmark8_Reference = 2105;
+ //[9] updates (teleport)
+ bool cfgBenchmark9_Enable = cfgEnable;
+ static const int cfgBenchmark9_Passes = 32;
+ static const int cfgBenchmark9_Iterations = 65536;
+ static const int cfgBenchmark9_Reference = 1879;
+ //[10] updates (jitter)
+ bool cfgBenchmark10_Enable = cfgEnable;
+ static const btScalar cfgBenchmark10_Scale = cfgVolumeCenterScale/10000;
+ static const int cfgBenchmark10_Passes = 32;
+ static const int cfgBenchmark10_Iterations = 65536;
+ static const int cfgBenchmark10_Reference = 1244;
+ //[11] optimize (incremental)
+ bool cfgBenchmark11_Enable = cfgEnable;
+ static const int cfgBenchmark11_Passes = 64;
+ static const int cfgBenchmark11_Iterations = 65536;
+ static const int cfgBenchmark11_Reference = 2510;
+ //[12] btDbvtVolume notequal
+ bool cfgBenchmark12_Enable = cfgEnable;
+ static const int cfgBenchmark12_Iterations = 32;
+ static const int cfgBenchmark12_Reference = 3677;
+ //[13] culling(OCL+fullsort)
+ bool cfgBenchmark13_Enable = cfgEnable;
+ static const int cfgBenchmark13_Iterations = 1024;
+ static const int cfgBenchmark13_Reference = 2231;
+ //[14] culling(OCL+qsort)
+ bool cfgBenchmark14_Enable = cfgEnable;
+ static const int cfgBenchmark14_Iterations = 8192;
+ static const int cfgBenchmark14_Reference = 3500;
+ //[15] culling(KDOP+qsort)
+ bool cfgBenchmark15_Enable = cfgEnable;
+ static const int cfgBenchmark15_Iterations = 8192;
+ static const int cfgBenchmark15_Reference = 1151;
+ //[16] insert/remove batch
+ bool cfgBenchmark16_Enable = cfgEnable;
+ static const int cfgBenchmark16_BatchCount = 256;
+ static const int cfgBenchmark16_Passes = 16384;
+ static const int cfgBenchmark16_Reference = 5138;
+ //[17] select
+ bool cfgBenchmark17_Enable = cfgEnable;
+ static const int cfgBenchmark17_Iterations = 4;
+ static const int cfgBenchmark17_Reference = 3390;
-btClock wallclock;
-printf("Benchmarking dbvt...\r\n");
-printf("\tWorld scale: %f\r\n",cfgVolumeCenterScale);
-printf("\tExtents base: %f\r\n",cfgVolumeExentsBase);
-printf("\tExtents range: %f\r\n",cfgVolumeExentsScale);
-printf("\tLeaves: %u\r\n",cfgLeaves);
-printf("\tsizeof(btDbvtVolume): %u bytes\r\n",sizeof(btDbvtVolume));
-printf("\tsizeof(btDbvtNode): %u bytes\r\n",sizeof(btDbvtNode));
-if(cfgBenchmark1_Enable)
+ btClock wallclock;
+ printf("Benchmarking dbvt...\r\n");
+ printf("\tWorld scale: %f\r\n",cfgVolumeCenterScale);
+ printf("\tExtents base: %f\r\n",cfgVolumeExentsBase);
+ printf("\tExtents range: %f\r\n",cfgVolumeExentsScale);
+ printf("\tLeaves: %u\r\n",cfgLeaves);
+ printf("\tsizeof(btDbvtVolume): %u bytes\r\n",sizeof(btDbvtVolume));
+ printf("\tsizeof(btDbvtNode): %u bytes\r\n",sizeof(btDbvtNode));
+ if(cfgBenchmark1_Enable)
{// Benchmark 1
- srand(380843);
- btAlignedObjectArray<btDbvtVolume> volumes;
- btAlignedObjectArray<bool> results;
- volumes.resize(cfgLeaves);
- results.resize(cfgLeaves);
- for(int i=0;i<cfgLeaves;++i)
+ srand(380843);
+ btAlignedObjectArray<btDbvtVolume> volumes;
+ btAlignedObjectArray<bool> results;
+ volumes.resize(cfgLeaves);
+ results.resize(cfgLeaves);
+ for(int i=0;i<cfgLeaves;++i)
{
- volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+ volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
}
- printf("[1] btDbvtVolume intersections: ");
- wallclock.reset();
- for(int i=0;i<cfgBenchmark1_Iterations;++i)
+ printf("[1] btDbvtVolume intersections: ");
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark1_Iterations;++i)
{
- for(int j=0;j<cfgLeaves;++j)
+ for(int j=0;j<cfgLeaves;++j)
{
- for(int k=0;k<cfgLeaves;++k)
+ for(int k=0;k<cfgLeaves;++k)
{
- results[k]=Intersect(volumes[j],volumes[k]);
+ results[k]=Intersect(volumes[j],volumes[k]);
}
}
}
- const int time=(int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark1_Reference)*100/time);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark1_Reference)*100/time);
}
-if(cfgBenchmark2_Enable)
+ if(cfgBenchmark2_Enable)
{// Benchmark 2
- srand(380843);
- btAlignedObjectArray<btDbvtVolume> volumes;
- btAlignedObjectArray<btDbvtVolume> results;
- volumes.resize(cfgLeaves);
- results.resize(cfgLeaves);
- for(int i=0;i<cfgLeaves;++i)
+ srand(380843);
+ btAlignedObjectArray<btDbvtVolume> volumes;
+ btAlignedObjectArray<btDbvtVolume> results;
+ volumes.resize(cfgLeaves);
+ results.resize(cfgLeaves);
+ for(int i=0;i<cfgLeaves;++i)
{
- volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+ volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
}
- printf("[2] btDbvtVolume merges: ");
- wallclock.reset();
- for(int i=0;i<cfgBenchmark2_Iterations;++i)
+ printf("[2] btDbvtVolume merges: ");
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark2_Iterations;++i)
{
- for(int j=0;j<cfgLeaves;++j)
+ for(int j=0;j<cfgLeaves;++j)
{
- for(int k=0;k<cfgLeaves;++k)
+ for(int k=0;k<cfgLeaves;++k)
{
- Merge(volumes[j],volumes[k],results[k]);
+ Merge(volumes[j],volumes[k],results[k]);
}
}
}
- const int time=(int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark2_Reference)*100/time);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark2_Reference)*100/time);
}
-if(cfgBenchmark3_Enable)
+ if(cfgBenchmark3_Enable)
{// Benchmark 3
- srand(380843);
- btDbvt dbvt[2];
- btDbvtBenchmark::NilPolicy policy;
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
- dbvt[0].optimizeTopDown();
- dbvt[1].optimizeTopDown();
- printf("[3] btDbvt::collideTT: ");
- wallclock.reset();
- for(int i=0;i<cfgBenchmark3_Iterations;++i)
+ srand(380843);
+ btDbvt dbvt[2];
+ btDbvtBenchmark::NilPolicy policy;
+ btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
+ btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
+ dbvt[0].optimizeTopDown();
+ dbvt[1].optimizeTopDown();
+ printf("[3] btDbvt::collideTT: ");
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark3_Iterations;++i)
{
- btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,policy);
+ btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,policy);
}
- const int time=(int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark3_Reference)*100/time);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark3_Reference)*100/time);
}
-if(cfgBenchmark4_Enable)
+ if(cfgBenchmark4_Enable)
{// Benchmark 4
- srand(380843);
- btDbvt dbvt;
- btDbvtBenchmark::NilPolicy policy;
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
- dbvt.optimizeTopDown();
- printf("[4] btDbvt::collideTT self: ");
- wallclock.reset();
- for(int i=0;i<cfgBenchmark4_Iterations;++i)
+ srand(380843);
+ btDbvt dbvt;
+ btDbvtBenchmark::NilPolicy policy;
+ btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+ dbvt.optimizeTopDown();
+ printf("[4] btDbvt::collideTT self: ");
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark4_Iterations;++i)
{
- btDbvt::collideTT(dbvt.m_root,dbvt.m_root,policy);
+ btDbvt::collideTT(dbvt.m_root,dbvt.m_root,policy);
}
- const int time=(int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark4_Reference)*100/time);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark4_Reference)*100/time);
}
-if(cfgBenchmark5_Enable)
+ if(cfgBenchmark5_Enable)
{// Benchmark 5
- srand(380843);
- btDbvt dbvt[2];
- btAlignedObjectArray<btTransform> transforms;
- btDbvtBenchmark::NilPolicy policy;
- transforms.resize(cfgBenchmark5_Iterations);
- for(int i=0;i<transforms.size();++i)
+ srand(380843);
+ btDbvt dbvt[2];
+ btAlignedObjectArray<btTransform> transforms;
+ btDbvtBenchmark::NilPolicy policy;
+ transforms.resize(cfgBenchmark5_Iterations);
+ for(int i=0;i<transforms.size();++i)
{
- transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark5_OffsetScale);
+ transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark5_OffsetScale);
}
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
- dbvt[0].optimizeTopDown();
- dbvt[1].optimizeTopDown();
- printf("[5] btDbvt::collideTT xform: ");
- wallclock.reset();
- for(int i=0;i<cfgBenchmark5_Iterations;++i)
+ btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
+ btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
+ dbvt[0].optimizeTopDown();
+ dbvt[1].optimizeTopDown();
+ printf("[5] btDbvt::collideTT xform: ");
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark5_Iterations;++i)
{
- btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,transforms[i],policy);
+ btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,transforms[i],policy);
}
- const int time=(int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark5_Reference)*100/time);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark5_Reference)*100/time);
}
-if(cfgBenchmark6_Enable)
+ if(cfgBenchmark6_Enable)
{// Benchmark 6
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<btTransform> transforms;
- btDbvtBenchmark::NilPolicy policy;
- transforms.resize(cfgBenchmark6_Iterations);
- for(int i=0;i<transforms.size();++i)
+ srand(380843);
+ btDbvt dbvt;
+ btAlignedObjectArray<btTransform> transforms;
+ btDbvtBenchmark::NilPolicy policy;
+ transforms.resize(cfgBenchmark6_Iterations);
+ for(int i=0;i<transforms.size();++i)
{
- transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark6_OffsetScale);
+ transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark6_OffsetScale);
}
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
- dbvt.optimizeTopDown();
- printf("[6] btDbvt::collideTT xform,self: ");
- wallclock.reset();
- for(int i=0;i<cfgBenchmark6_Iterations;++i)
+ btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+ dbvt.optimizeTopDown();
+ printf("[6] btDbvt::collideTT xform,self: ");
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark6_Iterations;++i)
{
- btDbvt::collideTT(dbvt.m_root,dbvt.m_root,transforms[i],policy);
+ btDbvt::collideTT(dbvt.m_root,dbvt.m_root,transforms[i],policy);
}
- const int time=(int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark6_Reference)*100/time);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark6_Reference)*100/time);
}
-if(cfgBenchmark7_Enable)
+ if(cfgBenchmark7_Enable)
{// Benchmark 7
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<btVector3> rayorg;
- btAlignedObjectArray<btVector3> raydir;
- btDbvtBenchmark::NilPolicy policy;
- rayorg.resize(cfgBenchmark7_Iterations);
- raydir.resize(cfgBenchmark7_Iterations);
- for(int i=0;i<rayorg.size();++i)
+ srand(380843);
+ btDbvt dbvt;
+ btAlignedObjectArray<btVector3> rayorg;
+ btAlignedObjectArray<btVector3> raydir;
+ btDbvtBenchmark::NilPolicy policy;
+ rayorg.resize(cfgBenchmark7_Iterations);
+ raydir.resize(cfgBenchmark7_Iterations);
+ for(int i=0;i<rayorg.size();++i)
{
- rayorg[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
- raydir[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
+ rayorg[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
+ raydir[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
}
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
- dbvt.optimizeTopDown();
- printf("[7] btDbvt::collideRAY: ");
- wallclock.reset();
- for(int i=0;i<cfgBenchmark7_Passes;++i)
+ btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+ dbvt.optimizeTopDown();
+ printf("[7] btDbvt::rayTest: ");
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark7_Passes;++i)
{
- for(int j=0;j<cfgBenchmark7_Iterations;++j)
+ for(int j=0;j<cfgBenchmark7_Iterations;++j)
{
- btDbvt::collideRAY(dbvt.m_root,rayorg[j],raydir[j],policy);
+ btDbvt::rayTest(dbvt.m_root,rayorg[j],rayorg[j]+raydir[j],policy);
}
}
- const int time=(int)wallclock.getTimeMilliseconds();
- unsigned rays=cfgBenchmark7_Passes*cfgBenchmark7_Iterations;
- printf("%u ms (%i%%),(%u r/s)\r\n",time,(time-cfgBenchmark7_Reference)*100/time,(rays*1000)/time);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ unsigned rays=cfgBenchmark7_Passes*cfgBenchmark7_Iterations;
+ printf("%u ms (%i%%),(%u r/s)\r\n",time,(time-cfgBenchmark7_Reference)*100/time,(rays*1000)/time);
}
-if(cfgBenchmark8_Enable)
+ if(cfgBenchmark8_Enable)
{// Benchmark 8
- srand(380843);
- btDbvt dbvt;
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
- dbvt.optimizeTopDown();
- printf("[8] insert/remove: ");
- wallclock.reset();
- for(int i=0;i<cfgBenchmark8_Passes;++i)
+ srand(380843);
+ btDbvt dbvt;
+ btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+ dbvt.optimizeTopDown();
+ printf("[8] insert/remove: ");
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark8_Passes;++i)
{
- for(int j=0;j<cfgBenchmark8_Iterations;++j)
+ for(int j=0;j<cfgBenchmark8_Iterations;++j)
{
- dbvt.remove(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
+ dbvt.remove(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
}
}
- const int time=(int)wallclock.getTimeMilliseconds();
- const int ir=cfgBenchmark8_Passes*cfgBenchmark8_Iterations;
- printf("%u ms (%i%%),(%u ir/s)\r\n",time,(time-cfgBenchmark8_Reference)*100/time,ir*1000/time);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ const int ir=cfgBenchmark8_Passes*cfgBenchmark8_Iterations;
+ printf("%u ms (%i%%),(%u ir/s)\r\n",time,(time-cfgBenchmark8_Reference)*100/time,ir*1000/time);
}
-if(cfgBenchmark9_Enable)
+ if(cfgBenchmark9_Enable)
{// Benchmark 9
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<const btDbvtNode*> leaves;
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
- dbvt.optimizeTopDown();
- dbvt.extractLeaves(dbvt.m_root,leaves);
- printf("[9] updates (teleport): ");
- wallclock.reset();
- for(int i=0;i<cfgBenchmark9_Passes;++i)
+ srand(380843);
+ btDbvt dbvt;
+ btAlignedObjectArray<const btDbvtNode*> leaves;
+ btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+ dbvt.optimizeTopDown();
+ dbvt.extractLeaves(dbvt.m_root,leaves);
+ printf("[9] updates (teleport): ");
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark9_Passes;++i)
{
- for(int j=0;j<cfgBenchmark9_Iterations;++j)
+ for(int j=0;j<cfgBenchmark9_Iterations;++j)
{
- dbvt.update(const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]),
- btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale));
+ dbvt.update(const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]),
+ btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale));
}
}
- const int time=(int)wallclock.getTimeMilliseconds();
- const int up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations;
- printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ const int up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations;
+ printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time);
}
-if(cfgBenchmark10_Enable)
+ if(cfgBenchmark10_Enable)
{// Benchmark 10
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<const btDbvtNode*> leaves;
- btAlignedObjectArray<btVector3> vectors;
- vectors.resize(cfgBenchmark10_Iterations);
- for(int i=0;i<vectors.size();++i)
+ srand(380843);
+ btDbvt dbvt;
+ btAlignedObjectArray<const btDbvtNode*> leaves;
+ btAlignedObjectArray<btVector3> vectors;
+ vectors.resize(cfgBenchmark10_Iterations);
+ for(int i=0;i<vectors.size();++i)
{
- vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1))*cfgBenchmark10_Scale;
+ vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1))*cfgBenchmark10_Scale;
}
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
- dbvt.optimizeTopDown();
- dbvt.extractLeaves(dbvt.m_root,leaves);
- printf("[10] updates (jitter): ");
- wallclock.reset();
-
- for(int i=0;i<cfgBenchmark10_Passes;++i)
+ btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+ dbvt.optimizeTopDown();
+ dbvt.extractLeaves(dbvt.m_root,leaves);
+ printf("[10] updates (jitter): ");
+ wallclock.reset();
+
+ for(int i=0;i<cfgBenchmark10_Passes;++i)
{
- for(int j=0;j<cfgBenchmark10_Iterations;++j)
+ for(int j=0;j<cfgBenchmark10_Iterations;++j)
{
- const btVector3& d=vectors[j];
- btDbvtNode* l=const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]);
- btDbvtVolume v=btDbvtVolume::FromMM(l->volume.Mins()+d,l->volume.Maxs()+d);
- dbvt.update(l,v);
+ const btVector3& d=vectors[j];
+ btDbvtNode* l=const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]);
+ btDbvtVolume v=btDbvtVolume::FromMM(l->volume.Mins()+d,l->volume.Maxs()+d);
+ dbvt.update(l,v);
}
}
- const int time=(int)wallclock.getTimeMilliseconds();
- const int up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations;
- printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ const int up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations;
+ printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time);
}
-if(cfgBenchmark11_Enable)
+ if(cfgBenchmark11_Enable)
{// Benchmark 11
- srand(380843);
- btDbvt dbvt;
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
- dbvt.optimizeTopDown();
- printf("[11] optimize (incremental): ");
- wallclock.reset();
- for(int i=0;i<cfgBenchmark11_Passes;++i)
+ srand(380843);
+ btDbvt dbvt;
+ btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+ dbvt.optimizeTopDown();
+ printf("[11] optimize (incremental): ");
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark11_Passes;++i)
{
- dbvt.optimizeIncremental(cfgBenchmark11_Iterations);
+ dbvt.optimizeIncremental(cfgBenchmark11_Iterations);
}
- const int time=(int)wallclock.getTimeMilliseconds();
- const int op=cfgBenchmark11_Passes*cfgBenchmark11_Iterations;
- printf("%u ms (%i%%),(%u o/s)\r\n",time,(time-cfgBenchmark11_Reference)*100/time,op/time*1000);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ const int op=cfgBenchmark11_Passes*cfgBenchmark11_Iterations;
+ printf("%u ms (%i%%),(%u o/s)\r\n",time,(time-cfgBenchmark11_Reference)*100/time,op/time*1000);
}
-if(cfgBenchmark12_Enable)
+ if(cfgBenchmark12_Enable)
{// Benchmark 12
- srand(380843);
- btAlignedObjectArray<btDbvtVolume> volumes;
- btAlignedObjectArray<bool> results;
- volumes.resize(cfgLeaves);
- results.resize(cfgLeaves);
- for(int i=0;i<cfgLeaves;++i)
+ srand(380843);
+ btAlignedObjectArray<btDbvtVolume> volumes;
+ btAlignedObjectArray<bool> results;
+ volumes.resize(cfgLeaves);
+ results.resize(cfgLeaves);
+ for(int i=0;i<cfgLeaves;++i)
{
- volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+ volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
}
- printf("[12] btDbvtVolume notequal: ");
- wallclock.reset();
- for(int i=0;i<cfgBenchmark12_Iterations;++i)
+ printf("[12] btDbvtVolume notequal: ");
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark12_Iterations;++i)
{
- for(int j=0;j<cfgLeaves;++j)
+ for(int j=0;j<cfgLeaves;++j)
{
- for(int k=0;k<cfgLeaves;++k)
+ for(int k=0;k<cfgLeaves;++k)
{
- results[k]=NotEqual(volumes[j],volumes[k]);
+ results[k]=NotEqual(volumes[j],volumes[k]);
}
}
}
- const int time=(int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark12_Reference)*100/time);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark12_Reference)*100/time);
}
-if(cfgBenchmark13_Enable)
+ if(cfgBenchmark13_Enable)
{// Benchmark 13
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<btVector3> vectors;
- btDbvtBenchmark::NilPolicy policy;
- vectors.resize(cfgBenchmark13_Iterations);
- for(int i=0;i<vectors.size();++i)
+ srand(380843);
+ btDbvt dbvt;
+ btAlignedObjectArray<btVector3> vectors;
+ btDbvtBenchmark::NilPolicy policy;
+ vectors.resize(cfgBenchmark13_Iterations);
+ for(int i=0;i<vectors.size();++i)
{
- vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
+ vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
}
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
- dbvt.optimizeTopDown();
- printf("[13] culling(OCL+fullsort): ");
- wallclock.reset();
- for(int i=0;i<cfgBenchmark13_Iterations;++i)
+ btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+ dbvt.optimizeTopDown();
+ printf("[13] culling(OCL+fullsort): ");
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark13_Iterations;++i)
{
- static const btScalar offset=0;
- policy.m_depth=-SIMD_INFINITY;
- dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy);
+ static const btScalar offset=0;
+ policy.m_depth=-SIMD_INFINITY;
+ dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy);
}
- const int time=(int)wallclock.getTimeMilliseconds();
- const int t=cfgBenchmark13_Iterations;
- printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark13_Reference)*100/time,(t*1000)/time);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ const int t=cfgBenchmark13_Iterations;
+ printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark13_Reference)*100/time,(t*1000)/time);
}
-if(cfgBenchmark14_Enable)
+ if(cfgBenchmark14_Enable)
{// Benchmark 14
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<btVector3> vectors;
- btDbvtBenchmark::P14 policy;
- vectors.resize(cfgBenchmark14_Iterations);
- for(int i=0;i<vectors.size();++i)
+ srand(380843);
+ btDbvt dbvt;
+ btAlignedObjectArray<btVector3> vectors;
+ btDbvtBenchmark::P14 policy;
+ vectors.resize(cfgBenchmark14_Iterations);
+ for(int i=0;i<vectors.size();++i)
{
- vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
+ vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
}
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
- dbvt.optimizeTopDown();
- policy.m_nodes.reserve(cfgLeaves);
- printf("[14] culling(OCL+qsort): ");
- wallclock.reset();
- for(int i=0;i<cfgBenchmark14_Iterations;++i)
+ btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+ dbvt.optimizeTopDown();
+ policy.m_nodes.reserve(cfgLeaves);
+ printf("[14] culling(OCL+qsort): ");
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark14_Iterations;++i)
{
- static const btScalar offset=0;
- policy.m_nodes.resize(0);
- dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy,false);
- policy.m_nodes.quickSort(btDbvtBenchmark::P14::sortfnc);
+ static const btScalar offset=0;
+ policy.m_nodes.resize(0);
+ dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy,false);
+ policy.m_nodes.quickSort(btDbvtBenchmark::P14::sortfnc);
}
- const int time=(int)wallclock.getTimeMilliseconds();
- const int t=cfgBenchmark14_Iterations;
- printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark14_Reference)*100/time,(t*1000)/time);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ const int t=cfgBenchmark14_Iterations;
+ printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark14_Reference)*100/time,(t*1000)/time);
}
-if(cfgBenchmark15_Enable)
+ if(cfgBenchmark15_Enable)
{// Benchmark 15
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<btVector3> vectors;
- btDbvtBenchmark::P15 policy;
- vectors.resize(cfgBenchmark15_Iterations);
- for(int i=0;i<vectors.size();++i)
+ srand(380843);
+ btDbvt dbvt;
+ btAlignedObjectArray<btVector3> vectors;
+ btDbvtBenchmark::P15 policy;
+ vectors.resize(cfgBenchmark15_Iterations);
+ for(int i=0;i<vectors.size();++i)
{
- vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
+ vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
}
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
- dbvt.optimizeTopDown();
- policy.m_nodes.reserve(cfgLeaves);
- printf("[15] culling(KDOP+qsort): ");
- wallclock.reset();
- for(int i=0;i<cfgBenchmark15_Iterations;++i)
+ btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+ dbvt.optimizeTopDown();
+ policy.m_nodes.reserve(cfgLeaves);
+ printf("[15] culling(KDOP+qsort): ");
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark15_Iterations;++i)
{
- static const btScalar offset=0;
- policy.m_nodes.resize(0);
- policy.m_axis=vectors[i];
- dbvt.collideKDOP(dbvt.m_root,&vectors[i],&offset,1,policy);
- policy.m_nodes.quickSort(btDbvtBenchmark::P15::sortfnc);
+ static const btScalar offset=0;
+ policy.m_nodes.resize(0);
+ policy.m_axis=vectors[i];
+ dbvt.collideKDOP(dbvt.m_root,&vectors[i],&offset,1,policy);
+ policy.m_nodes.quickSort(btDbvtBenchmark::P15::sortfnc);
}
- const int time=(int)wallclock.getTimeMilliseconds();
- const int t=cfgBenchmark15_Iterations;
- printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark15_Reference)*100/time,(t*1000)/time);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ const int t=cfgBenchmark15_Iterations;
+ printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark15_Reference)*100/time,(t*1000)/time);
}
-if(cfgBenchmark16_Enable)
+ if(cfgBenchmark16_Enable)
{// Benchmark 16
- srand(380843);
- btDbvt dbvt;
- btAlignedObjectArray<btDbvtNode*> batch;
- btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
- dbvt.optimizeTopDown();
- batch.reserve(cfgBenchmark16_BatchCount);
- printf("[16] insert/remove batch(%u): ",cfgBenchmark16_BatchCount);
- wallclock.reset();
- for(int i=0;i<cfgBenchmark16_Passes;++i)
+ srand(380843);
+ btDbvt dbvt;
+ btAlignedObjectArray<btDbvtNode*> batch;
+ btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+ dbvt.optimizeTopDown();
+ batch.reserve(cfgBenchmark16_BatchCount);
+ printf("[16] insert/remove batch(%u): ",cfgBenchmark16_BatchCount);
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark16_Passes;++i)
{
- for(int j=0;j<cfgBenchmark16_BatchCount;++j)
+ for(int j=0;j<cfgBenchmark16_BatchCount;++j)
{
- batch.push_back(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
+ batch.push_back(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
}
- for(int j=0;j<cfgBenchmark16_BatchCount;++j)
+ for(int j=0;j<cfgBenchmark16_BatchCount;++j)
{
- dbvt.remove(batch[j]);
+ dbvt.remove(batch[j]);
}
- batch.resize(0);
+ batch.resize(0);
}
- const int time=(int)wallclock.getTimeMilliseconds();
- const int ir=cfgBenchmark16_Passes*cfgBenchmark16_BatchCount;
- printf("%u ms (%i%%),(%u bir/s)\r\n",time,(time-cfgBenchmark16_Reference)*100/time,int(ir*1000.0/time));
+ const int time=(int)wallclock.getTimeMilliseconds();
+ const int ir=cfgBenchmark16_Passes*cfgBenchmark16_BatchCount;
+ printf("%u ms (%i%%),(%u bir/s)\r\n",time,(time-cfgBenchmark16_Reference)*100/time,int(ir*1000.0/time));
}
-if(cfgBenchmark17_Enable)
+ if(cfgBenchmark17_Enable)
{// Benchmark 17
- srand(380843);
- btAlignedObjectArray<btDbvtVolume> volumes;
- btAlignedObjectArray<int> results;
- btAlignedObjectArray<int> indices;
- volumes.resize(cfgLeaves);
- results.resize(cfgLeaves);
- indices.resize(cfgLeaves);
- for(int i=0;i<cfgLeaves;++i)
+ srand(380843);
+ btAlignedObjectArray<btDbvtVolume> volumes;
+ btAlignedObjectArray<int> results;
+ btAlignedObjectArray<int> indices;
+ volumes.resize(cfgLeaves);
+ results.resize(cfgLeaves);
+ indices.resize(cfgLeaves);
+ for(int i=0;i<cfgLeaves;++i)
{
- indices[i]=i;
- volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+ indices[i]=i;
+ volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
}
- for(int i=0;i<cfgLeaves;++i)
+ for(int i=0;i<cfgLeaves;++i)
{
- btSwap(indices[i],indices[rand()%cfgLeaves]);
+ btSwap(indices[i],indices[rand()%cfgLeaves]);
}
- printf("[17] btDbvtVolume select: ");
- wallclock.reset();
- for(int i=0;i<cfgBenchmark17_Iterations;++i)
+ printf("[17] btDbvtVolume select: ");
+ wallclock.reset();
+ for(int i=0;i<cfgBenchmark17_Iterations;++i)
{
- for(int j=0;j<cfgLeaves;++j)
+ for(int j=0;j<cfgLeaves;++j)
{
- for(int k=0;k<cfgLeaves;++k)
+ for(int k=0;k<cfgLeaves;++k)
{
- const int idx=indices[k];
- results[idx]=Select(volumes[idx],volumes[j],volumes[k]);
+ const int idx=indices[k];
+ results[idx]=Select(volumes[idx],volumes[j],volumes[k]);
}
}
}
- const int time=(int)wallclock.getTimeMilliseconds();
- printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark17_Reference)*100/time);
+ const int time=(int)wallclock.getTimeMilliseconds();
+ printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark17_Reference)*100/time);
}
-printf("\r\n\r\n");
+ printf("\r\n\r\n");
}
#endif
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.h
index 21d69acf151..d3cf1e75039 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.h
@@ -20,6 +20,7 @@ subject to the following restrictions:
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
+#include "LinearMath/btAabbUtil2.h"
//
// Compile time configuration
@@ -31,11 +32,11 @@ subject to the following restrictions:
#define DBVT_IMPL_SSE 1 // SSE
// Template implementation of ICollide
-#ifdef WIN32_AVOID_SSE_WHEN_EMBEDDED_INSIDE_BLENDER //there is always some weird compiler that breaks SSE builds
- #if (defined (_MSC_VER) && _MSC_VER >= 1400)
- #define DBVT_USE_TEMPLATE 1
- #else
- #define DBVT_USE_TEMPLATE 0
+#ifdef WIN32
+#if (defined (_MSC_VER) && _MSC_VER >= 1400)
+#define DBVT_USE_TEMPLATE 1
+#else
+#define DBVT_USE_TEMPLATE 0
#endif
#else
#define DBVT_USE_TEMPLATE 0
@@ -52,16 +53,11 @@ subject to the following restrictions:
// Inlining
#define DBVT_INLINE SIMD_FORCE_INLINE
-// Align
-#ifdef WIN32
-#define DBVT_ALIGN __declspec(align(16))
-#else
-#define DBVT_ALIGN
-#endif
// Specific methods implementation
-#ifdef WIN32_AVOID_SSE_WHEN_EMBEDDED_INSIDE_BLENDER //there is always some weird compiler that breaks SSE builds
+//SSE gives errors on a MSVC 7.1
+#ifdef BT_USE_SSE
#define DBVT_SELECT_IMPL DBVT_IMPL_SSE
#define DBVT_MERGE_IMPL DBVT_IMPL_SSE
#define DBVT_INT0_IMPL DBVT_IMPL_SSE
@@ -86,7 +82,7 @@ subject to the following restrictions:
#define DBVT_VIRTUAL_DTOR(a)
#define DBVT_PREFIX template <typename T>
#define DBVT_IPOLICY T& policy
-#define DBVT_CHECKTYPE static const ICollide& typechecker=*(T*)0;
+#define DBVT_CHECKTYPE static const ICollide& typechecker=*(T*)1;(void)typechecker;
#else
#define DBVT_VIRTUAL_DTOR(a) virtual ~a() {}
#define DBVT_VIRTUAL virtual
@@ -133,46 +129,41 @@ subject to the following restrictions:
/* btDbvtAabbMm */
struct btDbvtAabbMm
{
-DBVT_INLINE btVector3 Center() const { return((mi+mx)/2); }
-DBVT_INLINE btVector3 Lengths() const { return(mx-mi); }
-DBVT_INLINE btVector3 Extents() const { return((mx-mi)/2); }
-DBVT_INLINE const btVector3& Mins() const { return(mi); }
-DBVT_INLINE const btVector3& Maxs() const { return(mx); }
-static inline btDbvtAabbMm FromCE(const btVector3& c,const btVector3& e);
-static inline btDbvtAabbMm FromCR(const btVector3& c,btScalar r);
-static inline btDbvtAabbMm FromMM(const btVector3& mi,const btVector3& mx);
-static inline btDbvtAabbMm FromPoints(const btVector3* pts,int n);
-static inline btDbvtAabbMm FromPoints(const btVector3** ppts,int n);
-DBVT_INLINE void Expand(const btVector3& e);
-DBVT_INLINE void SignedExpand(const btVector3& e);
-DBVT_INLINE bool Contain(const btDbvtAabbMm& a) const;
-DBVT_INLINE int Classify(const btVector3& n,btScalar o,int s) const;
-DBVT_INLINE btScalar ProjectMinimum(const btVector3& v,unsigned signs) const;
-DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a,
- const btDbvtAabbMm& b);
-DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a,
- const btDbvtAabbMm& b,
- const btTransform& xform);
-DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a,
- const btVector3& b);
-DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a,
- const btVector3& org,
- const btVector3& invdir,
- const unsigned* signs);
-DBVT_INLINE friend btScalar Proximity( const btDbvtAabbMm& a,
- const btDbvtAabbMm& b);
-DBVT_INLINE friend int Select( const btDbvtAabbMm& o,
- const btDbvtAabbMm& a,
- const btDbvtAabbMm& b);
-DBVT_INLINE friend void Merge( const btDbvtAabbMm& a,
- const btDbvtAabbMm& b,
- btDbvtAabbMm& r);
-DBVT_INLINE friend bool NotEqual( const btDbvtAabbMm& a,
- const btDbvtAabbMm& b);
+ DBVT_INLINE btVector3 Center() const { return((mi+mx)/2); }
+ DBVT_INLINE btVector3 Lengths() const { return(mx-mi); }
+ DBVT_INLINE btVector3 Extents() const { return((mx-mi)/2); }
+ DBVT_INLINE const btVector3& Mins() const { return(mi); }
+ DBVT_INLINE const btVector3& Maxs() const { return(mx); }
+ static inline btDbvtAabbMm FromCE(const btVector3& c,const btVector3& e);
+ static inline btDbvtAabbMm FromCR(const btVector3& c,btScalar r);
+ static inline btDbvtAabbMm FromMM(const btVector3& mi,const btVector3& mx);
+ static inline btDbvtAabbMm FromPoints(const btVector3* pts,int n);
+ static inline btDbvtAabbMm FromPoints(const btVector3** ppts,int n);
+ DBVT_INLINE void Expand(const btVector3& e);
+ DBVT_INLINE void SignedExpand(const btVector3& e);
+ DBVT_INLINE bool Contain(const btDbvtAabbMm& a) const;
+ DBVT_INLINE int Classify(const btVector3& n,btScalar o,int s) const;
+ DBVT_INLINE btScalar ProjectMinimum(const btVector3& v,unsigned signs) const;
+ DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a,
+ const btDbvtAabbMm& b);
+
+ DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a,
+ const btVector3& b);
+
+ DBVT_INLINE friend btScalar Proximity( const btDbvtAabbMm& a,
+ const btDbvtAabbMm& b);
+ DBVT_INLINE friend int Select( const btDbvtAabbMm& o,
+ const btDbvtAabbMm& a,
+ const btDbvtAabbMm& b);
+ DBVT_INLINE friend void Merge( const btDbvtAabbMm& a,
+ const btDbvtAabbMm& b,
+ btDbvtAabbMm& r);
+ DBVT_INLINE friend bool NotEqual( const btDbvtAabbMm& a,
+ const btDbvtAabbMm& b);
private:
-DBVT_INLINE void AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const;
+ DBVT_INLINE void AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const;
private:
-btVector3 mi,mx;
+ btVector3 mi,mx;
};
// Types
@@ -185,88 +176,94 @@ struct btDbvtNode
btDbvtNode* parent;
DBVT_INLINE bool isleaf() const { return(childs[1]==0); }
DBVT_INLINE bool isinternal() const { return(!isleaf()); }
- union {
- btDbvtNode* childs[2];
- void* data;
- int dataAsInt;
- };
+ union
+ {
+ btDbvtNode* childs[2];
+ void* data;
+ int dataAsInt;
+ };
};
///The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes (aabb tree).
///This btDbvt is used for soft body collision detection and for the btDbvtBroadphase. It has a fast insert, remove and update of nodes.
///Unlike the btQuantizedBvh, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure.
struct btDbvt
- {
+{
/* Stack element */
struct sStkNN
- {
+ {
const btDbvtNode* a;
const btDbvtNode* b;
sStkNN() {}
sStkNN(const btDbvtNode* na,const btDbvtNode* nb) : a(na),b(nb) {}
- };
+ };
struct sStkNP
- {
+ {
const btDbvtNode* node;
int mask;
sStkNP(const btDbvtNode* n,unsigned m) : node(n),mask(m) {}
- };
+ };
struct sStkNPS
- {
+ {
const btDbvtNode* node;
int mask;
btScalar value;
sStkNPS() {}
sStkNPS(const btDbvtNode* n,unsigned m,btScalar v) : node(n),mask(m),value(v) {}
- };
+ };
struct sStkCLN
- {
+ {
const btDbvtNode* node;
btDbvtNode* parent;
sStkCLN(const btDbvtNode* n,btDbvtNode* p) : node(n),parent(p) {}
- };
+ };
// Policies/Interfaces
-
+
/* ICollide */
struct ICollide
- {
+ {
DBVT_VIRTUAL_DTOR(ICollide)
- DBVT_VIRTUAL void Process(const btDbvtNode*,const btDbvtNode*) {}
+ DBVT_VIRTUAL void Process(const btDbvtNode*,const btDbvtNode*) {}
DBVT_VIRTUAL void Process(const btDbvtNode*) {}
DBVT_VIRTUAL void Process(const btDbvtNode* n,btScalar) { Process(n); }
DBVT_VIRTUAL bool Descent(const btDbvtNode*) { return(true); }
DBVT_VIRTUAL bool AllLeaves(const btDbvtNode*) { return(true); }
- };
+ };
/* IWriter */
struct IWriter
- {
+ {
virtual ~IWriter() {}
virtual void Prepare(const btDbvtNode* root,int numnodes)=0;
virtual void WriteNode(const btDbvtNode*,int index,int parent,int child0,int child1)=0;
virtual void WriteLeaf(const btDbvtNode*,int index,int parent)=0;
- };
+ };
/* IClone */
struct IClone
- {
+ {
virtual ~IClone() {}
virtual void CloneLeaf(btDbvtNode*) {}
- };
-
+ };
+
// Constants
enum {
- SIMPLE_STACKSIZE = 64,
- DOUBLE_STACKSIZE = SIMPLE_STACKSIZE*2
- };
-
+ SIMPLE_STACKSIZE = 64,
+ DOUBLE_STACKSIZE = SIMPLE_STACKSIZE*2
+ };
+
// Fields
btDbvtNode* m_root;
btDbvtNode* m_free;
int m_lkhd;
int m_leaves;
unsigned m_opath;
+
+
+ btAlignedObjectArray<sStkNN> m_stkStack;
+
+
// Methods
- btDbvt();
- ~btDbvt();
+ btDbvt();
+ ~btDbvt();
void clear();
bool empty() const { return(0==m_root); }
void optimizeBottomUp();
@@ -274,95 +271,118 @@ struct btDbvt
void optimizeIncremental(int passes);
btDbvtNode* insert(const btDbvtVolume& box,void* data);
void update(btDbvtNode* leaf,int lookahead=-1);
- void update(btDbvtNode* leaf,const btDbvtVolume& volume);
- bool update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity,btScalar margin);
- bool update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity);
- bool update(btDbvtNode* leaf,btDbvtVolume volume,btScalar margin);
+ void update(btDbvtNode* leaf,btDbvtVolume& volume);
+ bool update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin);
+ bool update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity);
+ bool update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin);
void remove(btDbvtNode* leaf);
void write(IWriter* iwriter) const;
void clone(btDbvt& dest,IClone* iclone=0) const;
static int maxdepth(const btDbvtNode* node);
static int countLeaves(const btDbvtNode* node);
static void extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves);
- #if DBVT_ENABLE_BENCHMARK
+#if DBVT_ENABLE_BENCHMARK
static void benchmark();
- #else
+#else
static void benchmark(){}
- #endif
+#endif
// DBVT_IPOLICY must support ICollide policy/interface
DBVT_PREFIX
- static void enumNodes( const btDbvtNode* root,
- DBVT_IPOLICY);
+ static void enumNodes( const btDbvtNode* root,
+ DBVT_IPOLICY);
+ DBVT_PREFIX
+ static void enumLeaves( const btDbvtNode* root,
+ DBVT_IPOLICY);
DBVT_PREFIX
- static void enumLeaves( const btDbvtNode* root,
- DBVT_IPOLICY);
+ void collideTT( const btDbvtNode* root0,
+ const btDbvtNode* root1,
+ DBVT_IPOLICY);
+
DBVT_PREFIX
- static void collideTT( const btDbvtNode* root0,
- const btDbvtNode* root1,
- DBVT_IPOLICY);
+ void collideTTpersistentStack( const btDbvtNode* root0,
+ const btDbvtNode* root1,
+ DBVT_IPOLICY);
+#if 0
DBVT_PREFIX
- static void collideTT( const btDbvtNode* root0,
- const btDbvtNode* root1,
- const btTransform& xform,
- DBVT_IPOLICY);
+ void collideTT( const btDbvtNode* root0,
+ const btDbvtNode* root1,
+ const btTransform& xform,
+ DBVT_IPOLICY);
DBVT_PREFIX
- static void collideTT( const btDbvtNode* root0,
- const btTransform& xform0,
- const btDbvtNode* root1,
- const btTransform& xform1,
- DBVT_IPOLICY);
+ void collideTT( const btDbvtNode* root0,
+ const btTransform& xform0,
+ const btDbvtNode* root1,
+ const btTransform& xform1,
+ DBVT_IPOLICY);
+#endif
+
DBVT_PREFIX
- static void collideTV( const btDbvtNode* root,
- const btDbvtVolume& volume,
- DBVT_IPOLICY);
+ void collideTV( const btDbvtNode* root,
+ const btDbvtVolume& volume,
+ DBVT_IPOLICY);
+ ///rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thread-safe (uses locking etc)
+ ///rayTest is slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time
DBVT_PREFIX
- static void collideRAY( const btDbvtNode* root,
- const btVector3& origin,
- const btVector3& direction,
- DBVT_IPOLICY);
+ static void rayTest( const btDbvtNode* root,
+ const btVector3& rayFrom,
+ const btVector3& rayTo,
+ DBVT_IPOLICY);
+ ///rayTestInternal is faster than rayTest, because it uses a persistent stack (to reduce dynamic memory allocations to a minimum) and it uses precomputed signs/rayInverseDirections
+ ///rayTestInternal is used by btDbvtBroadphase to accelerate world ray casts
DBVT_PREFIX
- static void collideKDOP(const btDbvtNode* root,
- const btVector3* normals,
- const btScalar* offsets,
- int count,
- DBVT_IPOLICY);
+ void rayTestInternal( const btDbvtNode* root,
+ const btVector3& rayFrom,
+ const btVector3& rayTo,
+ const btVector3& rayDirectionInverse,
+ unsigned int signs[3],
+ btScalar lambda_max,
+ const btVector3& aabbMin,
+ const btVector3& aabbMax,
+ DBVT_IPOLICY) const;
+
DBVT_PREFIX
- static void collideOCL( const btDbvtNode* root,
- const btVector3* normals,
- const btScalar* offsets,
- const btVector3& sortaxis,
- int count,
- DBVT_IPOLICY,
- bool fullsort=true);
+ static void collideKDOP(const btDbvtNode* root,
+ const btVector3* normals,
+ const btScalar* offsets,
+ int count,
+ DBVT_IPOLICY);
DBVT_PREFIX
- static void collideTU( const btDbvtNode* root,
- DBVT_IPOLICY);
+ static void collideOCL( const btDbvtNode* root,
+ const btVector3* normals,
+ const btScalar* offsets,
+ const btVector3& sortaxis,
+ int count,
+ DBVT_IPOLICY,
+ bool fullsort=true);
+ DBVT_PREFIX
+ static void collideTU( const btDbvtNode* root,
+ DBVT_IPOLICY);
// Helpers
static DBVT_INLINE int nearest(const int* i,const btDbvt::sStkNPS* a,btScalar v,int l,int h)
- {
+ {
int m=0;
while(l<h)
- {
+ {
m=(l+h)>>1;
if(a[i[m]].value>=v) l=m+1; else h=m;
- }
- return(h);
}
+ return(h);
+ }
static DBVT_INLINE int allocate( btAlignedObjectArray<int>& ifree,
- btAlignedObjectArray<sStkNPS>& stock,
- const sStkNPS& value)
- {
+ btAlignedObjectArray<sStkNPS>& stock,
+ const sStkNPS& value)
+ {
int i;
if(ifree.size()>0)
- { i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; }
- else
- { i=stock.size();stock.push_back(value); }
+ { i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; }
+ else
+ { i=stock.size();stock.push_back(value); }
return(i);
- }
+ }
//
- private:
- btDbvt(const btDbvt&) {}
- };
+private:
+ btDbvt(const btDbvt&) {}
+};
//
// Inline's
@@ -371,69 +391,69 @@ struct btDbvt
//
inline btDbvtAabbMm btDbvtAabbMm::FromCE(const btVector3& c,const btVector3& e)
{
-btDbvtAabbMm box;
-box.mi=c-e;box.mx=c+e;
-return(box);
+ btDbvtAabbMm box;
+ box.mi=c-e;box.mx=c+e;
+ return(box);
}
-
+
//
inline btDbvtAabbMm btDbvtAabbMm::FromCR(const btVector3& c,btScalar r)
{
-return(FromCE(c,btVector3(r,r,r)));
+ return(FromCE(c,btVector3(r,r,r)));
}
-
+
//
inline btDbvtAabbMm btDbvtAabbMm::FromMM(const btVector3& mi,const btVector3& mx)
{
-btDbvtAabbMm box;
-box.mi=mi;box.mx=mx;
-return(box);
+ btDbvtAabbMm box;
+ box.mi=mi;box.mx=mx;
+ return(box);
}
-
+
//
inline btDbvtAabbMm btDbvtAabbMm::FromPoints(const btVector3* pts,int n)
{
-btDbvtAabbMm box;
-box.mi=box.mx=pts[0];
-for(int i=1;i<n;++i)
+ btDbvtAabbMm box;
+ box.mi=box.mx=pts[0];
+ for(int i=1;i<n;++i)
{
- box.mi.setMin(pts[i]);
- box.mx.setMax(pts[i]);
+ box.mi.setMin(pts[i]);
+ box.mx.setMax(pts[i]);
}
-return(box);
+ return(box);
}
//
inline btDbvtAabbMm btDbvtAabbMm::FromPoints(const btVector3** ppts,int n)
{
-btDbvtAabbMm box;
-box.mi=box.mx=*ppts[0];
-for(int i=1;i<n;++i)
+ btDbvtAabbMm box;
+ box.mi=box.mx=*ppts[0];
+ for(int i=1;i<n;++i)
{
- box.mi.setMin(*ppts[i]);
- box.mx.setMax(*ppts[i]);
+ box.mi.setMin(*ppts[i]);
+ box.mx.setMax(*ppts[i]);
}
-return(box);
+ return(box);
}
//
DBVT_INLINE void btDbvtAabbMm::Expand(const btVector3& e)
{
-mi-=e;mx+=e;
+ mi-=e;mx+=e;
}
-
+
//
DBVT_INLINE void btDbvtAabbMm::SignedExpand(const btVector3& e)
{
-if(e.x()>0) mx.setX(mx.x()+e[0]); else mi.setX(mi.x()+e[0]);
-if(e.y()>0) mx.setY(mx.y()+e[1]); else mi.setY(mi.y()+e[1]);
-if(e.z()>0) mx.setZ(mx.z()+e[2]); else mi.setZ(mi.z()+e[2]);
+ if(e.x()>0) mx.setX(mx.x()+e[0]); else mi.setX(mi.x()+e[0]);
+ if(e.y()>0) mx.setY(mx.y()+e[1]); else mi.setY(mi.y()+e[1]);
+ if(e.z()>0) mx.setZ(mx.z()+e[2]); else mi.setZ(mi.z()+e[2]);
}
-
+
//
DBVT_INLINE bool btDbvtAabbMm::Contain(const btDbvtAabbMm& a) const
{
-return( (mi.x()<=a.mi.x())&&
+ return( (mi.x()<=a.mi.x())&&
(mi.y()<=a.mi.y())&&
(mi.z()<=a.mi.z())&&
(mx.x()>=a.mx.x())&&
@@ -444,64 +464,64 @@ return( (mi.x()<=a.mi.x())&&
//
DBVT_INLINE int btDbvtAabbMm::Classify(const btVector3& n,btScalar o,int s) const
{
-btVector3 pi,px;
-switch(s)
+ btVector3 pi,px;
+ switch(s)
{
case (0+0+0): px=btVector3(mi.x(),mi.y(),mi.z());
- pi=btVector3(mx.x(),mx.y(),mx.z());break;
+ pi=btVector3(mx.x(),mx.y(),mx.z());break;
case (1+0+0): px=btVector3(mx.x(),mi.y(),mi.z());
- pi=btVector3(mi.x(),mx.y(),mx.z());break;
+ pi=btVector3(mi.x(),mx.y(),mx.z());break;
case (0+2+0): px=btVector3(mi.x(),mx.y(),mi.z());
- pi=btVector3(mx.x(),mi.y(),mx.z());break;
+ pi=btVector3(mx.x(),mi.y(),mx.z());break;
case (1+2+0): px=btVector3(mx.x(),mx.y(),mi.z());
- pi=btVector3(mi.x(),mi.y(),mx.z());break;
+ pi=btVector3(mi.x(),mi.y(),mx.z());break;
case (0+0+4): px=btVector3(mi.x(),mi.y(),mx.z());
- pi=btVector3(mx.x(),mx.y(),mi.z());break;
+ pi=btVector3(mx.x(),mx.y(),mi.z());break;
case (1+0+4): px=btVector3(mx.x(),mi.y(),mx.z());
- pi=btVector3(mi.x(),mx.y(),mi.z());break;
+ pi=btVector3(mi.x(),mx.y(),mi.z());break;
case (0+2+4): px=btVector3(mi.x(),mx.y(),mx.z());
- pi=btVector3(mx.x(),mi.y(),mi.z());break;
+ pi=btVector3(mx.x(),mi.y(),mi.z());break;
case (1+2+4): px=btVector3(mx.x(),mx.y(),mx.z());
- pi=btVector3(mi.x(),mi.y(),mi.z());break;
+ pi=btVector3(mi.x(),mi.y(),mi.z());break;
}
-if((dot(n,px)+o)<0) return(-1);
-if((dot(n,pi)+o)>=0) return(+1);
-return(0);
+ if((dot(n,px)+o)<0) return(-1);
+ if((dot(n,pi)+o)>=0) return(+1);
+ return(0);
}
//
DBVT_INLINE btScalar btDbvtAabbMm::ProjectMinimum(const btVector3& v,unsigned signs) const
{
-const btVector3* b[]={&mx,&mi};
-const btVector3 p( b[(signs>>0)&1]->x(),
- b[(signs>>1)&1]->y(),
- b[(signs>>2)&1]->z());
-return(dot(p,v));
+ const btVector3* b[]={&mx,&mi};
+ const btVector3 p( b[(signs>>0)&1]->x(),
+ b[(signs>>1)&1]->y(),
+ b[(signs>>2)&1]->z());
+ return(dot(p,v));
}
//
DBVT_INLINE void btDbvtAabbMm::AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const
{
-for(int i=0;i<3;++i)
+ for(int i=0;i<3;++i)
{
- if(d[i]<0)
+ if(d[i]<0)
{ smi+=mx[i]*d[i];smx+=mi[i]*d[i]; }
else
{ smi+=mi[i]*d[i];smx+=mx[i]*d[i]; }
}
}
-
+
//
DBVT_INLINE bool Intersect( const btDbvtAabbMm& a,
- const btDbvtAabbMm& b)
+ const btDbvtAabbMm& b)
{
#if DBVT_INT0_IMPL == DBVT_IMPL_SSE
-const __m128 rt(_mm_or_ps( _mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)),
- _mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi))));
-const __int32* pu((const __int32*)&rt);
-return((pu[0]|pu[1]|pu[2])==0);
+ const __m128 rt(_mm_or_ps( _mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)),
+ _mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi))));
+ const __int32* pu((const __int32*)&rt);
+ return((pu[0]|pu[1]|pu[2])==0);
#else
-return( (a.mi.x()<=b.mx.x())&&
+ return( (a.mi.x()<=b.mx.x())&&
(a.mx.x()>=b.mi.x())&&
(a.mi.y()<=b.mx.y())&&
(a.mx.y()>=b.mi.y())&&
@@ -510,27 +530,13 @@ return( (a.mi.x()<=b.mx.x())&&
#endif
}
-//
-DBVT_INLINE bool Intersect( const btDbvtAabbMm& a,
- const btDbvtAabbMm& b,
- const btTransform& xform)
-{
-const btVector3 d0=xform*b.Center()-a.Center();
-const btVector3 d1=d0*xform.getBasis();
-btScalar s0[2]={0,0};
-btScalar s1[2]={dot(xform.getOrigin(),d0),s1[0]};
-a.AddSpan(d0,s0[0],s0[1]);
-b.AddSpan(d1,s1[0],s1[1]);
-if(s0[0]>(s1[1])) return(false);
-if(s0[1]<(s1[0])) return(false);
-return(true);
-}
+
//
DBVT_INLINE bool Intersect( const btDbvtAabbMm& a,
- const btVector3& b)
+ const btVector3& b)
{
-return( (b.x()>=a.mi.x())&&
+ return( (b.x()>=a.mi.x())&&
(b.y()>=a.mi.y())&&
(b.z()>=a.mi.z())&&
(b.x()<=a.mx.x())&&
@@ -538,55 +544,40 @@ return( (b.x()>=a.mi.x())&&
(b.z()<=a.mx.z()));
}
-//
-DBVT_INLINE bool Intersect( const btDbvtAabbMm& a,
- const btVector3& org,
- const btVector3& invdir,
- const unsigned* signs)
-{
-#if 0
-const btVector3 b0((a.mi-org)*invdir);
-const btVector3 b1((a.mx-org)*invdir);
-const btVector3 tmin(btMin(b0[0],b1[0]),btMin(b0[1],b1[1]),btMin(b0[2],b1[2]));
-const btVector3 tmax(btMax(b0[0],b1[0]),btMax(b0[1],b1[1]),btMax(b0[2],b1[2]));
-const btScalar tin=btMax(tmin[0],btMax(tmin[1],tmin[2]));
-const btScalar tout=btMin(tmax[0],btMin(tmax[1],tmax[2]));
-return(tin<tout);
-#else
-const btVector3* bounds[2]={&a.mi,&a.mx};
-btScalar txmin=(bounds[ signs[0]]->x()-org[0])*invdir[0];
-btScalar txmax=(bounds[1-signs[0]]->x()-org[0])*invdir[0];
-const btScalar tymin=(bounds[ signs[1]]->y()-org[1])*invdir[1];
-const btScalar tymax=(bounds[1-signs[1]]->y()-org[1])*invdir[1];
-if((txmin>tymax)||(tymin>txmax)) return(false);
-if(tymin>txmin) txmin=tymin;
-if(tymax<txmax) txmax=tymax;
-const btScalar tzmin=(bounds[ signs[2]]->z()-org[2])*invdir[2];
-const btScalar tzmax=(bounds[1-signs[2]]->z()-org[2])*invdir[2];
-if((txmin>tzmax)||(tzmin>txmax)) return(false);
-if(tzmin>txmin) txmin=tzmin;
-if(tzmax<txmax) txmax=tzmax;
-return(txmax>0);
-#endif
-}
-
+
+
+
+
+//////////////////////////////////////
+
+
//
DBVT_INLINE btScalar Proximity( const btDbvtAabbMm& a,
- const btDbvtAabbMm& b)
+ const btDbvtAabbMm& b)
{
-const btVector3 d=(a.mi+a.mx)-(b.mi+b.mx);
-return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
+ const btVector3 d=(a.mi+a.mx)-(b.mi+b.mx);
+ return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
}
+
+
//
DBVT_INLINE int Select( const btDbvtAabbMm& o,
- const btDbvtAabbMm& a,
- const btDbvtAabbMm& b)
+ const btDbvtAabbMm& a,
+ const btDbvtAabbMm& b)
{
#if DBVT_SELECT_IMPL == DBVT_IMPL_SSE
-static DBVT_ALIGN const unsigned __int32 mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff};
- // TODO: the intrinsic version is 11% slower
- #if DBVT_USE_INTRINSIC_SSE
+ static ATTRIBUTE_ALIGNED16(const unsigned __int32) mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff};
+ ///@todo: the intrinsic version is 11% slower
+#if DBVT_USE_INTRINSIC_SSE
+
+ union btSSEUnion ///NOTE: if we use more intrinsics, move btSSEUnion into the LinearMath directory
+ {
+ __m128 ssereg;
+ float floats[4];
+ int ints[4];
+ };
+
__m128 omi(_mm_load_ps(o.mi));
omi=_mm_add_ps(omi,_mm_load_ps(o.mx));
__m128 ami(_mm_load_ps(a.mi));
@@ -600,74 +591,78 @@ static DBVT_ALIGN const unsigned __int32 mask[]={0x7fffffff,0x7fffffff,0x7ffffff
__m128 t0(_mm_movehl_ps(ami,ami));
ami=_mm_add_ps(ami,t0);
ami=_mm_add_ss(ami,_mm_shuffle_ps(ami,ami,1));
- __m128 t1(_mm_movehl_ps(bmi,bmi));
+ __m128 t1(_mm_movehl_ps(bmi,bmi));
bmi=_mm_add_ps(bmi,t1);
bmi=_mm_add_ss(bmi,_mm_shuffle_ps(bmi,bmi,1));
- return(_mm_cmple_ss(bmi,ami).m128_u32[0]&1);
- #else
- DBVT_ALIGN __int32 r[1];
+
+ btSSEUnion tmp;
+ tmp.ssereg = _mm_cmple_ss(bmi,ami);
+ return tmp.ints[0]&1;
+
+#else
+ ATTRIBUTE_ALIGNED16(__int32 r[1]);
__asm
- {
+ {
mov eax,o
- mov ecx,a
- mov edx,b
- movaps xmm0,[eax]
+ mov ecx,a
+ mov edx,b
+ movaps xmm0,[eax]
movaps xmm5,mask
- addps xmm0,[eax+16]
+ addps xmm0,[eax+16]
movaps xmm1,[ecx]
movaps xmm2,[edx]
addps xmm1,[ecx+16]
addps xmm2,[edx+16]
subps xmm1,xmm0
- subps xmm2,xmm0
- andps xmm1,xmm5
- andps xmm2,xmm5
- movhlps xmm3,xmm1
- movhlps xmm4,xmm2
- addps xmm1,xmm3
- addps xmm2,xmm4
- pshufd xmm3,xmm1,1
- pshufd xmm4,xmm2,1
- addss xmm1,xmm3
- addss xmm2,xmm4
- cmpless xmm2,xmm1
- movss r,xmm2
- }
+ subps xmm2,xmm0
+ andps xmm1,xmm5
+ andps xmm2,xmm5
+ movhlps xmm3,xmm1
+ movhlps xmm4,xmm2
+ addps xmm1,xmm3
+ addps xmm2,xmm4
+ pshufd xmm3,xmm1,1
+ pshufd xmm4,xmm2,1
+ addss xmm1,xmm3
+ addss xmm2,xmm4
+ cmpless xmm2,xmm1
+ movss r,xmm2
+ }
return(r[0]&1);
- #endif
+#endif
#else
-return(Proximity(o,a)<Proximity(o,b)?0:1);
+ return(Proximity(o,a)<Proximity(o,b)?0:1);
#endif
}
//
DBVT_INLINE void Merge( const btDbvtAabbMm& a,
- const btDbvtAabbMm& b,
- btDbvtAabbMm& r)
+ const btDbvtAabbMm& b,
+ btDbvtAabbMm& r)
{
#if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
-__m128 ami(_mm_load_ps(a.mi));
-__m128 amx(_mm_load_ps(a.mx));
-__m128 bmi(_mm_load_ps(b.mi));
-__m128 bmx(_mm_load_ps(b.mx));
-ami=_mm_min_ps(ami,bmi);
-amx=_mm_max_ps(amx,bmx);
-_mm_store_ps(r.mi,ami);
-_mm_store_ps(r.mx,amx);
+ __m128 ami(_mm_load_ps(a.mi));
+ __m128 amx(_mm_load_ps(a.mx));
+ __m128 bmi(_mm_load_ps(b.mi));
+ __m128 bmx(_mm_load_ps(b.mx));
+ ami=_mm_min_ps(ami,bmi);
+ amx=_mm_max_ps(amx,bmx);
+ _mm_store_ps(r.mi,ami);
+ _mm_store_ps(r.mx,amx);
#else
-for(int i=0;i<3;++i)
+ for(int i=0;i<3;++i)
{
- if(a.mi[i]<b.mi[i]) r.mi[i]=a.mi[i]; else r.mi[i]=b.mi[i];
- if(a.mx[i]>b.mx[i]) r.mx[i]=a.mx[i]; else r.mx[i]=b.mx[i];
+ if(a.mi[i]<b.mi[i]) r.mi[i]=a.mi[i]; else r.mi[i]=b.mi[i];
+ if(a.mx[i]>b.mx[i]) r.mx[i]=a.mx[i]; else r.mx[i]=b.mx[i];
}
#endif
}
//
DBVT_INLINE bool NotEqual( const btDbvtAabbMm& a,
- const btDbvtAabbMm& b)
+ const btDbvtAabbMm& b)
{
-return( (a.mi.x()!=b.mi.x())||
+ return( (a.mi.x()!=b.mi.x())||
(a.mi.y()!=b.mi.y())||
(a.mi.z()!=b.mi.z())||
(a.mx.x()!=b.mx.x())||
@@ -682,235 +677,383 @@ return( (a.mi.x()!=b.mi.x())||
//
DBVT_PREFIX
inline void btDbvt::enumNodes( const btDbvtNode* root,
- DBVT_IPOLICY)
+ DBVT_IPOLICY)
{
-DBVT_CHECKTYPE
-policy.Process(root);
-if(root->isinternal())
+ DBVT_CHECKTYPE
+ policy.Process(root);
+ if(root->isinternal())
{
- enumNodes(root->childs[0],policy);
- enumNodes(root->childs[1],policy);
+ enumNodes(root->childs[0],policy);
+ enumNodes(root->childs[1],policy);
}
}
//
DBVT_PREFIX
inline void btDbvt::enumLeaves( const btDbvtNode* root,
- DBVT_IPOLICY)
+ DBVT_IPOLICY)
{
-DBVT_CHECKTYPE
-if(root->isinternal())
- {
- enumLeaves(root->childs[0],policy);
- enumLeaves(root->childs[1],policy);
- }
- else
- {
- policy.Process(root);
- }
+ DBVT_CHECKTYPE
+ if(root->isinternal())
+ {
+ enumLeaves(root->childs[0],policy);
+ enumLeaves(root->childs[1],policy);
+ }
+ else
+ {
+ policy.Process(root);
+ }
}
//
DBVT_PREFIX
inline void btDbvt::collideTT( const btDbvtNode* root0,
- const btDbvtNode* root1,
- DBVT_IPOLICY)
+ const btDbvtNode* root1,
+ DBVT_IPOLICY)
{
-DBVT_CHECKTYPE
-if(root0&&root1)
- {
- btAlignedObjectArray<sStkNN> stack;
- int depth=1;
- int treshold=DOUBLE_STACKSIZE-4;
- stack.resize(DOUBLE_STACKSIZE);
- stack[0]=sStkNN(root0,root1);
- do {
- sStkNN p=stack[--depth];
- if(depth>treshold)
- {
- stack.resize(stack.size()*2);
- treshold=stack.size()-4;
- }
- if(p.a==p.b)
- {
- if(p.a->isinternal())
+ DBVT_CHECKTYPE
+ if(root0&&root1)
+ {
+ int depth=1;
+ int treshold=DOUBLE_STACKSIZE-4;
+ btAlignedObjectArray<sStkNN> stkStack;
+ stkStack.resize(DOUBLE_STACKSIZE);
+ stkStack[0]=sStkNN(root0,root1);
+ do {
+ sStkNN p=stkStack[--depth];
+ if(depth>treshold)
{
- stack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
- stack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
- stack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
+ stkStack.resize(stkStack.size()*2);
+ treshold=stkStack.size()-4;
}
- }
- else if(Intersect(p.a->volume,p.b->volume))
- {
- if(p.a->isinternal())
+ if(p.a==p.b)
{
- if(p.b->isinternal())
+ if(p.a->isinternal())
{
- stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
- stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
- stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
- stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
- }
- else
- {
- stack[depth++]=sStkNN(p.a->childs[0],p.b);
- stack[depth++]=sStkNN(p.a->childs[1],p.b);
+ stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
+ stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
+ stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
}
}
- else
+ else if(Intersect(p.a->volume,p.b->volume))
{
- if(p.b->isinternal())
+ if(p.a->isinternal())
{
- stack[depth++]=sStkNN(p.a,p.b->childs[0]);
- stack[depth++]=sStkNN(p.a,p.b->childs[1]);
+ if(p.b->isinternal())
+ {
+ stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
+ stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
+ stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
+ stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
+ }
+ else
+ {
+ stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
+ stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
+ }
}
else
{
- policy.Process(p.a,p.b);
+ if(p.b->isinternal())
+ {
+ stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
+ stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
+ }
+ else
+ {
+ policy.Process(p.a,p.b);
+ }
}
}
- }
- } while(depth);
- }
+ } while(depth);
+ }
}
-//
+
+
DBVT_PREFIX
-inline void btDbvt::collideTT( const btDbvtNode* root0,
- const btDbvtNode* root1,
- const btTransform& xform,
- DBVT_IPOLICY)
+inline void btDbvt::collideTTpersistentStack( const btDbvtNode* root0,
+ const btDbvtNode* root1,
+ DBVT_IPOLICY)
{
-DBVT_CHECKTYPE
-if(root0&&root1)
- {
- btAlignedObjectArray<sStkNN> stack;
- int depth=1;
- int treshold=DOUBLE_STACKSIZE-4;
- stack.resize(DOUBLE_STACKSIZE);
- stack[0]=sStkNN(root0,root1);
- do {
- sStkNN p=stack[--depth];
- if(Intersect(p.a->volume,p.b->volume,xform))
- {
- if(depth>treshold)
+ DBVT_CHECKTYPE
+ if(root0&&root1)
+ {
+ int depth=1;
+ int treshold=DOUBLE_STACKSIZE-4;
+
+ m_stkStack.resize(DOUBLE_STACKSIZE);
+ m_stkStack[0]=sStkNN(root0,root1);
+ do {
+ sStkNN p=m_stkStack[--depth];
+ if(depth>treshold)
{
- stack.resize(stack.size()*2);
- treshold=stack.size()-4;
+ m_stkStack.resize(m_stkStack.size()*2);
+ treshold=m_stkStack.size()-4;
}
- if(p.a->isinternal())
+ if(p.a==p.b)
{
- if(p.b->isinternal())
- {
- stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
- stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
- stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
- stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
+ if(p.a->isinternal())
+ {
+ m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
+ m_stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
+ m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
+ }
+ }
+ else if(Intersect(p.a->volume,p.b->volume))
+ {
+ if(p.a->isinternal())
+ {
+ if(p.b->isinternal())
+ {
+ m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
+ m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
+ m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
+ m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
+ }
+ else
+ {
+ m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
+ m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
+ }
}
else
{
- stack[depth++]=sStkNN(p.a->childs[0],p.b);
- stack[depth++]=sStkNN(p.a->childs[1],p.b);
+ if(p.b->isinternal())
+ {
+ m_stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
+ m_stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
+ }
+ else
+ {
+ policy.Process(p.a,p.b);
+ }
}
}
- else
+ } while(depth);
+ }
+}
+
+#if 0
+//
+DBVT_PREFIX
+inline void btDbvt::collideTT( const btDbvtNode* root0,
+ const btDbvtNode* root1,
+ const btTransform& xform,
+ DBVT_IPOLICY)
+{
+ DBVT_CHECKTYPE
+ if(root0&&root1)
+ {
+ int depth=1;
+ int treshold=DOUBLE_STACKSIZE-4;
+ btAlignedObjectArray<sStkNN> stkStack;
+ stkStack.resize(DOUBLE_STACKSIZE);
+ stkStack[0]=sStkNN(root0,root1);
+ do {
+ sStkNN p=stkStack[--depth];
+ if(Intersect(p.a->volume,p.b->volume,xform))
{
- if(p.b->isinternal())
+ if(depth>treshold)
{
- stack[depth++]=sStkNN(p.a,p.b->childs[0]);
- stack[depth++]=sStkNN(p.a,p.b->childs[1]);
+ stkStack.resize(stkStack.size()*2);
+ treshold=stkStack.size()-4;
+ }
+ if(p.a->isinternal())
+ {
+ if(p.b->isinternal())
+ {
+ stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
+ stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
+ stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
+ stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
+ }
+ else
+ {
+ stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
+ stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
+ }
}
else
{
- policy.Process(p.a,p.b);
+ if(p.b->isinternal())
+ {
+ stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
+ stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
+ }
+ else
+ {
+ policy.Process(p.a,p.b);
+ }
}
}
- }
- } while(depth);
- }
+ } while(depth);
+ }
}
-
//
DBVT_PREFIX
inline void btDbvt::collideTT( const btDbvtNode* root0,
- const btTransform& xform0,
- const btDbvtNode* root1,
- const btTransform& xform1,
- DBVT_IPOLICY)
+ const btTransform& xform0,
+ const btDbvtNode* root1,
+ const btTransform& xform1,
+ DBVT_IPOLICY)
{
-const btTransform xform=xform0.inverse()*xform1;
-collideTT(root0,root1,xform,policy);
+ const btTransform xform=xform0.inverse()*xform1;
+ collideTT(root0,root1,xform,policy);
}
+#endif
//
DBVT_PREFIX
inline void btDbvt::collideTV( const btDbvtNode* root,
- const btDbvtVolume& vol,
- DBVT_IPOLICY)
+ const btDbvtVolume& vol,
+ DBVT_IPOLICY)
+{
+ DBVT_CHECKTYPE
+ if(root)
+ {
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol);
+ btAlignedObjectArray<const btDbvtNode*> stack;
+ stack.resize(0);
+ stack.reserve(SIMPLE_STACKSIZE);
+ stack.push_back(root);
+ do {
+ const btDbvtNode* n=stack[stack.size()-1];
+ stack.pop_back();
+ if(Intersect(n->volume,volume))
+ {
+ if(n->isinternal())
+ {
+ stack.push_back(n->childs[0]);
+ stack.push_back(n->childs[1]);
+ }
+ else
+ {
+ policy.Process(n);
+ }
+ }
+ } while(stack.size()>0);
+ }
+}
+
+DBVT_PREFIX
+inline void btDbvt::rayTestInternal( const btDbvtNode* root,
+ const btVector3& rayFrom,
+ const btVector3& rayTo,
+ const btVector3& rayDirectionInverse,
+ unsigned int signs[3],
+ btScalar lambda_max,
+ const btVector3& aabbMin,
+ const btVector3& aabbMax,
+ DBVT_IPOLICY) const
{
-DBVT_CHECKTYPE
-if(root)
+ DBVT_CHECKTYPE
+ if(root)
{
- ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol);
- btAlignedObjectArray<const btDbvtNode*> stack;
- stack.reserve(SIMPLE_STACKSIZE);
- stack.push_back(root);
- do {
- const btDbvtNode* n=stack[stack.size()-1];
- stack.pop_back();
- if(Intersect(n->volume,volume))
+ btVector3 resultNormal;
+
+ int depth=1;
+ int treshold=DOUBLE_STACKSIZE-2;
+ btAlignedObjectArray<const btDbvtNode*> stack;
+ stack.resize(DOUBLE_STACKSIZE);
+ stack[0]=root;
+ btVector3 bounds[2];
+ do
+ {
+ const btDbvtNode* node=stack[--depth];
+ bounds[0] = node->volume.Mins()+aabbMin;
+ bounds[1] = node->volume.Maxs()+aabbMax;
+ btScalar tmin=1.f,lambda_min=0.f;
+ unsigned int result1=false;
+ result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);
+ if(result1)
{
- if(n->isinternal())
+ if(node->isinternal())
{
- stack.push_back(n->childs[0]);
- stack.push_back(n->childs[1]);
+ if(depth>treshold)
+ {
+ stack.resize(stack.size()*2);
+ treshold=stack.size()-2;
+ }
+ stack[depth++]=node->childs[0];
+ stack[depth++]=node->childs[1];
}
else
{
- policy.Process(n);
+ policy.Process(node);
}
}
- } while(stack.size()>0);
+ } while(depth);
}
}
//
DBVT_PREFIX
-inline void btDbvt::collideRAY( const btDbvtNode* root,
- const btVector3& origin,
- const btVector3& direction,
- DBVT_IPOLICY)
+inline void btDbvt::rayTest( const btDbvtNode* root,
+ const btVector3& rayFrom,
+ const btVector3& rayTo,
+ DBVT_IPOLICY)
{
-DBVT_CHECKTYPE
-if(root)
- {
- const btVector3 normal=direction.normalized();
- const btVector3 invdir( 1/normal.x(),
- 1/normal.y(),
- 1/normal.z());
- const unsigned signs[]={ direction.x()<0,
- direction.y()<0,
- direction.z()<0};
- btAlignedObjectArray<const btDbvtNode*> stack;
- stack.reserve(SIMPLE_STACKSIZE);
- stack.push_back(root);
- do {
- const btDbvtNode* node=stack[stack.size()-1];
- stack.pop_back();
- if(Intersect(node->volume,origin,invdir,signs))
- {
- if(node->isinternal())
- {
- stack.push_back(node->childs[0]);
- stack.push_back(node->childs[1]);
- }
- else
+ DBVT_CHECKTYPE
+ if(root)
+ {
+ btVector3 rayDir = (rayTo-rayFrom);
+ rayDir.normalize ();
+
+ ///what about division by zero? --> just set rayDirection[i] to INF/1e30
+ btVector3 rayDirectionInverse;
+ rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
+ rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
+ rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+ unsigned int signs[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
+
+ btScalar lambda_max = rayDir.dot(rayTo-rayFrom);
+
+ btVector3 resultNormal;
+
+ btAlignedObjectArray<const btDbvtNode*> stack;
+
+ int depth=1;
+ int treshold=DOUBLE_STACKSIZE-2;
+
+ stack.resize(DOUBLE_STACKSIZE);
+ stack[0]=root;
+ btVector3 bounds[2];
+ do {
+ const btDbvtNode* node=stack[--depth];
+
+ bounds[0] = node->volume.Mins();
+ bounds[1] = node->volume.Maxs();
+
+ btScalar tmin=1.f,lambda_min=0.f;
+ unsigned int result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);
+
+#ifdef COMPARE_BTRAY_AABB2
+ btScalar param=1.f;
+ bool result2 = btRayAabb(rayFrom,rayTo,node->volume.Mins(),node->volume.Maxs(),param,resultNormal);
+ btAssert(result1 == result2);
+#endif //TEST_BTRAY_AABB2
+
+ if(result1)
{
- policy.Process(node);
+ if(node->isinternal())
+ {
+ if(depth>treshold)
+ {
+ stack.resize(stack.size()*2);
+ treshold=stack.size()-2;
+ }
+ stack[depth++]=node->childs[0];
+ stack[depth++]=node->childs[1];
+ }
+ else
+ {
+ policy.Process(node);
+ }
}
- }
- } while(stack.size());
- }
+ } while(depth);
+
+ }
}
//
@@ -921,174 +1064,174 @@ inline void btDbvt::collideKDOP(const btDbvtNode* root,
int count,
DBVT_IPOLICY)
{
-DBVT_CHECKTYPE
-if(root)
- {
- const int inside=(1<<count)-1;
- btAlignedObjectArray<sStkNP> stack;
- int signs[sizeof(unsigned)*8];
- btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
- for(int i=0;i<count;++i)
+ DBVT_CHECKTYPE
+ if(root)
{
- signs[i]= ((normals[i].x()>=0)?1:0)+
+ const int inside=(1<<count)-1;
+ btAlignedObjectArray<sStkNP> stack;
+ int signs[sizeof(unsigned)*8];
+ btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
+ for(int i=0;i<count;++i)
+ {
+ signs[i]= ((normals[i].x()>=0)?1:0)+
((normals[i].y()>=0)?2:0)+
((normals[i].z()>=0)?4:0);
- }
- stack.reserve(SIMPLE_STACKSIZE);
- stack.push_back(sStkNP(root,0));
- do {
- sStkNP se=stack[stack.size()-1];
- bool out=false;
- stack.pop_back();
- for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
- {
- if(0==(se.mask&j))
+ }
+ stack.reserve(SIMPLE_STACKSIZE);
+ stack.push_back(sStkNP(root,0));
+ do {
+ sStkNP se=stack[stack.size()-1];
+ bool out=false;
+ stack.pop_back();
+ for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
{
- const int side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
- switch(side)
+ if(0==(se.mask&j))
{
- case -1: out=true;break;
- case +1: se.mask|=j;break;
+ const int side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
+ switch(side)
+ {
+ case -1: out=true;break;
+ case +1: se.mask|=j;break;
+ }
}
}
- }
- if(!out)
- {
- if((se.mask!=inside)&&(se.node->isinternal()))
- {
- stack.push_back(sStkNP(se.node->childs[0],se.mask));
- stack.push_back(sStkNP(se.node->childs[1],se.mask));
- }
- else
+ if(!out)
{
- if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy);
+ if((se.mask!=inside)&&(se.node->isinternal()))
+ {
+ stack.push_back(sStkNP(se.node->childs[0],se.mask));
+ stack.push_back(sStkNP(se.node->childs[1],se.mask));
+ }
+ else
+ {
+ if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy);
+ }
}
- }
- } while(stack.size());
- }
+ } while(stack.size());
+ }
}
//
DBVT_PREFIX
inline void btDbvt::collideOCL( const btDbvtNode* root,
- const btVector3* normals,
- const btScalar* offsets,
- const btVector3& sortaxis,
- int count,
- DBVT_IPOLICY,
- bool fsort)
+ const btVector3* normals,
+ const btScalar* offsets,
+ const btVector3& sortaxis,
+ int count,
+ DBVT_IPOLICY,
+ bool fsort)
{
-DBVT_CHECKTYPE
-if(root)
- {
- const unsigned srtsgns=(sortaxis[0]>=0?1:0)+
- (sortaxis[1]>=0?2:0)+
- (sortaxis[2]>=0?4:0);
- const int inside=(1<<count)-1;
- btAlignedObjectArray<sStkNPS> stock;
- btAlignedObjectArray<int> ifree;
- btAlignedObjectArray<int> stack;
- int signs[sizeof(unsigned)*8];
- btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
- for(int i=0;i<count;++i)
+ DBVT_CHECKTYPE
+ if(root)
{
- signs[i]= ((normals[i].x()>=0)?1:0)+
+ const unsigned srtsgns=(sortaxis[0]>=0?1:0)+
+ (sortaxis[1]>=0?2:0)+
+ (sortaxis[2]>=0?4:0);
+ const int inside=(1<<count)-1;
+ btAlignedObjectArray<sStkNPS> stock;
+ btAlignedObjectArray<int> ifree;
+ btAlignedObjectArray<int> stack;
+ int signs[sizeof(unsigned)*8];
+ btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
+ for(int i=0;i<count;++i)
+ {
+ signs[i]= ((normals[i].x()>=0)?1:0)+
((normals[i].y()>=0)?2:0)+
((normals[i].z()>=0)?4:0);
- }
- stock.reserve(SIMPLE_STACKSIZE);
- stack.reserve(SIMPLE_STACKSIZE);
- ifree.reserve(SIMPLE_STACKSIZE);
- stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns))));
- do {
- const int id=stack[stack.size()-1];
- sStkNPS se=stock[id];
- stack.pop_back();ifree.push_back(id);
- if(se.mask!=inside)
- {
- bool out=false;
- for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
+ }
+ stock.reserve(SIMPLE_STACKSIZE);
+ stack.reserve(SIMPLE_STACKSIZE);
+ ifree.reserve(SIMPLE_STACKSIZE);
+ stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns))));
+ do {
+ const int id=stack[stack.size()-1];
+ sStkNPS se=stock[id];
+ stack.pop_back();ifree.push_back(id);
+ if(se.mask!=inside)
{
- if(0==(se.mask&j))
+ bool out=false;
+ for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
{
- const int side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
- switch(side)
+ if(0==(se.mask&j))
{
- case -1: out=true;break;
- case +1: se.mask|=j;break;
+ const int side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
+ switch(side)
+ {
+ case -1: out=true;break;
+ case +1: se.mask|=j;break;
+ }
}
}
+ if(out) continue;
}
- if(out) continue;
- }
- if(policy.Descent(se.node))
- {
- if(se.node->isinternal())
+ if(policy.Descent(se.node))
{
- const btDbvtNode* pns[]={ se.node->childs[0],se.node->childs[1]};
- sStkNPS nes[]={ sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)),
- sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))};
- const int q=nes[0].value<nes[1].value?1:0;
- int j=stack.size();
- if(fsort&&(j>0))
+ if(se.node->isinternal())
{
- /* Insert 0 */
- j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size());
- stack.push_back(0);
- #if DBVT_USE_MEMMOVE
- memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
- #else
- for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
- #endif
- stack[j]=allocate(ifree,stock,nes[q]);
- /* Insert 1 */
- j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size());
- stack.push_back(0);
- #if DBVT_USE_MEMMOVE
- memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
- #else
- for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
- #endif
- stack[j]=allocate(ifree,stock,nes[1-q]);
+ const btDbvtNode* pns[]={ se.node->childs[0],se.node->childs[1]};
+ sStkNPS nes[]={ sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)),
+ sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))};
+ const int q=nes[0].value<nes[1].value?1:0;
+ int j=stack.size();
+ if(fsort&&(j>0))
+ {
+ /* Insert 0 */
+ j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size());
+ stack.push_back(0);
+#if DBVT_USE_MEMMOVE
+ memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
+#else
+ for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
+#endif
+ stack[j]=allocate(ifree,stock,nes[q]);
+ /* Insert 1 */
+ j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size());
+ stack.push_back(0);
+#if DBVT_USE_MEMMOVE
+ memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
+#else
+ for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
+#endif
+ stack[j]=allocate(ifree,stock,nes[1-q]);
+ }
+ else
+ {
+ stack.push_back(allocate(ifree,stock,nes[q]));
+ stack.push_back(allocate(ifree,stock,nes[1-q]));
+ }
}
else
{
- stack.push_back(allocate(ifree,stock,nes[q]));
- stack.push_back(allocate(ifree,stock,nes[1-q]));
+ policy.Process(se.node,se.value);
}
}
- else
- {
- policy.Process(se.node,se.value);
- }
- }
- } while(stack.size());
- }
+ } while(stack.size());
+ }
}
//
DBVT_PREFIX
inline void btDbvt::collideTU( const btDbvtNode* root,
- DBVT_IPOLICY)
+ DBVT_IPOLICY)
{
-DBVT_CHECKTYPE
-if(root)
- {
- btAlignedObjectArray<const btDbvtNode*> stack;
- stack.reserve(SIMPLE_STACKSIZE);
- stack.push_back(root);
- do {
- const btDbvtNode* n=stack[stack.size()-1];
- stack.pop_back();
- if(policy.Descent(n))
- {
- if(n->isinternal())
- { stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); }
- else
- { policy.Process(n); }
- }
- } while(stack.size()>0);
- }
+ DBVT_CHECKTYPE
+ if(root)
+ {
+ btAlignedObjectArray<const btDbvtNode*> stack;
+ stack.reserve(SIMPLE_STACKSIZE);
+ stack.push_back(root);
+ do {
+ const btDbvtNode* n=stack[stack.size()-1];
+ stack.pop_back();
+ if(policy.Descent(n))
+ {
+ if(n->isinternal())
+ { stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); }
+ else
+ { policy.Process(n); }
+ }
+ } while(stack.size()>0);
+ }
}
//
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp
index e00fc6aa5e3..f231717af17 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp
@@ -26,19 +26,19 @@ subject to the following restrictions:
#if DBVT_BP_PROFILE
struct ProfileScope
- {
+{
__forceinline ProfileScope(btClock& clock,unsigned long& value) :
- m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds())
- {
- }
+ m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds())
+ {
+ }
__forceinline ~ProfileScope()
- {
+ {
(*m_value)+=m_clock->getTimeMicroseconds()-m_base;
- }
+ }
btClock* m_clock;
unsigned long* m_value;
unsigned long m_base;
- };
+};
#define SPC(_value_) ProfileScope spc_scope(m_clock,_value_)
#else
#define SPC(_value_)
@@ -52,35 +52,35 @@ struct ProfileScope
template <typename T>
static inline void listappend(T* item,T*& list)
{
-item->links[0]=0;
-item->links[1]=list;
-if(list) list->links[0]=item;
-list=item;
+ item->links[0]=0;
+ item->links[1]=list;
+ if(list) list->links[0]=item;
+ list=item;
}
//
template <typename T>
static inline void listremove(T* item,T*& list)
{
-if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1];
-if(item->links[1]) item->links[1]->links[0]=item->links[0];
+ if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1];
+ if(item->links[1]) item->links[1]->links[0]=item->links[0];
}
//
template <typename T>
static inline int listcount(T* root)
{
-int n=0;
-while(root) { ++n;root=root->links[1]; }
-return(n);
+ int n=0;
+ while(root) { ++n;root=root->links[1]; }
+ return(n);
}
//
template <typename T>
static inline void clear(T& value)
{
-static const struct ZeroDummy : T {} zerodummy;
-value=zerodummy;
+ static const struct ZeroDummy : T {} zerodummy;
+ value=zerodummy;
}
//
@@ -90,25 +90,26 @@ value=zerodummy;
/* Tree collider */
struct btDbvtTreeCollider : btDbvt::ICollide
{
-btDbvtBroadphase* pbp;
-btDbvtProxy* proxy;
- btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {}
-void Process(const btDbvtNode* na,const btDbvtNode* nb)
+ btDbvtBroadphase* pbp;
+ btDbvtProxy* proxy;
+ btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {}
+ void Process(const btDbvtNode* na,const btDbvtNode* nb)
{
- if(na!=nb)
+ if(na!=nb)
{
- btDbvtProxy* pa=(btDbvtProxy*)na->data;
- btDbvtProxy* pb=(btDbvtProxy*)nb->data;
- #if DBVT_BP_SORTPAIRS
- if(pa>pb) btSwap(pa,pb);
- #endif
- pbp->m_paircache->addOverlappingPair(pa,pb);
- ++pbp->m_newpairs;
+ btDbvtProxy* pa=(btDbvtProxy*)na->data;
+ btDbvtProxy* pb=(btDbvtProxy*)nb->data;
+#if DBVT_BP_SORTPAIRS
+ if(pa->m_uniqueId>pb->m_uniqueId)
+ btSwap(pa,pb);
+#endif
+ pbp->m_paircache->addOverlappingPair(pa,pb);
+ ++pbp->m_newpairs;
}
}
-void Process(const btDbvtNode* n)
+ void Process(const btDbvtNode* n)
{
- Process(n,proxy->leaf);
+ Process(n,proxy->leaf);
}
};
@@ -119,147 +120,197 @@ void Process(const btDbvtNode* n)
//
btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache* paircache)
{
-m_deferedcollide = false;
-m_needcleanup = true;
-m_releasepaircache = (paircache!=0)?false:true;
-m_prediction = 1/(btScalar)2;
-m_stageCurrent = 0;
-m_fixedleft = 0;
-m_fupdates = 1;
-m_dupdates = 0;
-m_cupdates = 10;
-m_newpairs = 1;
-m_updates_call = 0;
-m_updates_done = 0;
-m_updates_ratio = 0;
-m_paircache = paircache?
- paircache :
- new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();
-m_gid = 0;
-m_pid = 0;
-m_cid = 0;
-for(int i=0;i<=STAGECOUNT;++i)
+ m_deferedcollide = false;
+ m_needcleanup = true;
+ m_releasepaircache = (paircache!=0)?false:true;
+ m_prediction = 1/(btScalar)2;
+ m_stageCurrent = 0;
+ m_fixedleft = 0;
+ m_fupdates = 1;
+ m_dupdates = 0;
+ m_cupdates = 10;
+ m_newpairs = 1;
+ m_updates_call = 0;
+ m_updates_done = 0;
+ m_updates_ratio = 0;
+ m_paircache = paircache? paircache : new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();
+ m_gid = 0;
+ m_pid = 0;
+ m_cid = 0;
+ for(int i=0;i<=STAGECOUNT;++i)
{
- m_stageRoots[i]=0;
+ m_stageRoots[i]=0;
}
#if DBVT_BP_PROFILE
-clear(m_profiling);
+ clear(m_profiling);
#endif
}
//
btDbvtBroadphase::~btDbvtBroadphase()
{
-if(m_releasepaircache)
-{
- m_paircache->~btOverlappingPairCache();
- btAlignedFree(m_paircache);
-}
+ if(m_releasepaircache)
+ {
+ m_paircache->~btOverlappingPairCache();
+ btAlignedFree(m_paircache);
+ }
}
//
btBroadphaseProxy* btDbvtBroadphase::createProxy( const btVector3& aabbMin,
- const btVector3& aabbMax,
- int /*shapeType*/,
- void* userPtr,
- short int collisionFilterGroup,
- short int collisionFilterMask,
- btDispatcher* /*dispatcher*/,
- void* /*multiSapProxy*/)
+ const btVector3& aabbMax,
+ int /*shapeType*/,
+ void* userPtr,
+ short int collisionFilterGroup,
+ short int collisionFilterMask,
+ btDispatcher* /*dispatcher*/,
+ void* /*multiSapProxy*/)
{
-btDbvtProxy* proxy=new(btAlignedAlloc(sizeof(btDbvtProxy),16)) btDbvtProxy( userPtr,
- collisionFilterGroup,
- collisionFilterMask);
-proxy->aabb = btDbvtVolume::FromMM(aabbMin,aabbMax);
-proxy->stage = m_stageCurrent;
-proxy->m_uniqueId = ++m_gid;
-proxy->leaf = m_sets[0].insert(proxy->aabb,proxy);
-listappend(proxy,m_stageRoots[m_stageCurrent]);
-if(!m_deferedcollide)
+ btDbvtProxy* proxy=new(btAlignedAlloc(sizeof(btDbvtProxy),16)) btDbvtProxy( aabbMin,aabbMax,userPtr,
+ collisionFilterGroup,
+ collisionFilterMask);
+
+ btDbvtAabbMm aabb = btDbvtVolume::FromMM(aabbMin,aabbMax);
+
+ //bproxy->aabb = btDbvtVolume::FromMM(aabbMin,aabbMax);
+ proxy->stage = m_stageCurrent;
+ proxy->m_uniqueId = ++m_gid;
+ proxy->leaf = m_sets[0].insert(aabb,proxy);
+ listappend(proxy,m_stageRoots[m_stageCurrent]);
+ if(!m_deferedcollide)
{
- btDbvtTreeCollider collider(this);
- collider.proxy=proxy;
- btDbvt::collideTV(m_sets[0].m_root,proxy->aabb,collider);
- btDbvt::collideTV(m_sets[1].m_root,proxy->aabb,collider);
+ btDbvtTreeCollider collider(this);
+ collider.proxy=proxy;
+ m_sets[0].collideTV(m_sets[0].m_root,aabb,collider);
+ m_sets[1].collideTV(m_sets[1].m_root,aabb,collider);
}
-return(proxy);
+ return(proxy);
}
//
void btDbvtBroadphase::destroyProxy( btBroadphaseProxy* absproxy,
- btDispatcher* dispatcher)
+ btDispatcher* dispatcher)
{
-btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
-if(proxy->stage==STAGECOUNT)
- m_sets[1].remove(proxy->leaf);
+ btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
+ if(proxy->stage==STAGECOUNT)
+ m_sets[1].remove(proxy->leaf);
else
- m_sets[0].remove(proxy->leaf);
-listremove(proxy,m_stageRoots[proxy->stage]);
-m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher);
-btAlignedFree(proxy);
-m_needcleanup=true;
+ m_sets[0].remove(proxy->leaf);
+ listremove(proxy,m_stageRoots[proxy->stage]);
+ m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher);
+ btAlignedFree(proxy);
+ m_needcleanup=true;
+}
+
+void btDbvtBroadphase::getAabb(btBroadphaseProxy* absproxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+ btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
+ aabbMin = proxy->m_aabbMin;
+ aabbMax = proxy->m_aabbMax;
+}
+
+struct BroadphaseRayTester : btDbvt::ICollide
+{
+ btBroadphaseRayCallback& m_rayCallback;
+ BroadphaseRayTester(btBroadphaseRayCallback& orgCallback)
+ :m_rayCallback(orgCallback)
+ {
+ }
+ void Process(const btDbvtNode* leaf)
+ {
+ btDbvtProxy* proxy=(btDbvtProxy*)leaf->data;
+ m_rayCallback.process(proxy);
+ }
+};
+
+void btDbvtBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax)
+{
+ BroadphaseRayTester callback(rayCallback);
+
+ m_sets[0].rayTestInternal( m_sets[0].m_root,
+ rayFrom,
+ rayTo,
+ rayCallback.m_rayDirectionInverse,
+ rayCallback.m_signs,
+ rayCallback.m_lambda_max,
+ aabbMin,
+ aabbMax,
+ callback);
+
+ m_sets[1].rayTestInternal( m_sets[1].m_root,
+ rayFrom,
+ rayTo,
+ rayCallback.m_rayDirectionInverse,
+ rayCallback.m_signs,
+ rayCallback.m_lambda_max,
+ aabbMin,
+ aabbMax,
+ callback);
+
}
//
void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy,
- const btVector3& aabbMin,
- const btVector3& aabbMax,
- btDispatcher* /*dispatcher*/)
+ const btVector3& aabbMin,
+ const btVector3& aabbMax,
+ btDispatcher* /*dispatcher*/)
{
-btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
-ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax);
+ btDbvtProxy* proxy=(btDbvtProxy*)absproxy;
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax);
#if DBVT_BP_PREVENTFALSEUPDATE
-if(NotEqual(aabb,proxy->leaf->volume))
+ if(NotEqual(aabb,proxy->leaf->volume))
#endif
{
- bool docollide=false;
- if(proxy->stage==STAGECOUNT)
+ bool docollide=false;
+ if(proxy->stage==STAGECOUNT)
{/* fixed -> dynamic set */
- m_sets[1].remove(proxy->leaf);
- proxy->leaf=m_sets[0].insert(aabb,proxy);
- docollide=true;
+ m_sets[1].remove(proxy->leaf);
+ proxy->leaf=m_sets[0].insert(aabb,proxy);
+ docollide=true;
}
else
{/* dynamic set */
- ++m_updates_call;
- if(Intersect(proxy->leaf->volume,aabb))
+ ++m_updates_call;
+ if(Intersect(proxy->leaf->volume,aabb))
{/* Moving */
- const btVector3 delta=aabbMin-proxy->aabb.Mins();
- btVector3 velocity(aabb.Extents()*m_prediction);
- if(delta[0]<0) velocity[0]=-velocity[0];
- if(delta[1]<0) velocity[1]=-velocity[1];
- if(delta[2]<0) velocity[2]=-velocity[2];
- if (
- #ifdef DBVT_BP_MARGIN
- m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN)
- #else
- m_sets[0].update(proxy->leaf,aabb,velocity)
- #endif
- )
+
+ const btVector3 delta=aabbMin-proxy->m_aabbMin;
+ btVector3 velocity(((proxy->m_aabbMax-proxy->m_aabbMin)/2)*m_prediction);
+ if(delta[0]<0) velocity[0]=-velocity[0];
+ if(delta[1]<0) velocity[1]=-velocity[1];
+ if(delta[2]<0) velocity[2]=-velocity[2];
+ if (
+#ifdef DBVT_BP_MARGIN
+ m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN)
+#else
+ m_sets[0].update(proxy->leaf,aabb,velocity)
+#endif
+ )
{
- ++m_updates_done;
- docollide=true;
+ ++m_updates_done;
+ docollide=true;
}
}
else
{/* Teleporting */
- m_sets[0].update(proxy->leaf,aabb);
- ++m_updates_done;
- docollide=true;
+ m_sets[0].update(proxy->leaf,aabb);
+ ++m_updates_done;
+ docollide=true;
}
}
- listremove(proxy,m_stageRoots[proxy->stage]);
- proxy->aabb = aabb;
- proxy->stage = m_stageCurrent;
- listappend(proxy,m_stageRoots[m_stageCurrent]);
- if(docollide)
+ listremove(proxy,m_stageRoots[proxy->stage]);
+ proxy->m_aabbMin = aabbMin;
+ proxy->m_aabbMax = aabbMax;
+ proxy->stage = m_stageCurrent;
+ listappend(proxy,m_stageRoots[m_stageCurrent]);
+ if(docollide)
{
- m_needcleanup=true;
- if(!m_deferedcollide)
+ m_needcleanup=true;
+ if(!m_deferedcollide)
{
- btDbvtTreeCollider collider(this);
- btDbvt::collideTT(m_sets[1].m_root,proxy->leaf,collider);
- btDbvt::collideTT(m_sets[0].m_root,proxy->leaf,collider);
+ btDbvtTreeCollider collider(this);
+ m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider);
+ m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider);
}
}
}
@@ -268,132 +319,226 @@ if(NotEqual(aabb,proxy->leaf->volume))
//
void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
{
-collide(dispatcher);
+ collide(dispatcher);
#if DBVT_BP_PROFILE
-if(0==(m_pid%DBVT_BP_PROFILING_RATE))
+ if(0==(m_pid%DBVT_BP_PROFILING_RATE))
{
- printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leaves,m_sets[0].m_leaves,m_paircache->getNumOverlappingPairs());
- unsigned int total=m_profiling.m_total;
- if(total<=0) total=1;
- printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE);
- printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE);
- printf("cleanup: %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE);
- printf("total: %uus\r\n",total/DBVT_BP_PROFILING_RATE);
- const unsigned long sum=m_profiling.m_ddcollide+
- m_profiling.m_fdcollide+
- m_profiling.m_cleanup;
- printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE);
- printf("job counts: %u%%\r\n",(m_profiling.m_jobcount*100)/((m_sets[0].m_leaves+m_sets[1].m_leaves)*DBVT_BP_PROFILING_RATE));
- clear(m_profiling);
- m_clock.reset();
+ printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leaves,m_sets[0].m_leaves,m_paircache->getNumOverlappingPairs());
+ unsigned int total=m_profiling.m_total;
+ if(total<=0) total=1;
+ printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE);
+ printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE);
+ printf("cleanup: %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE);
+ printf("total: %uus\r\n",total/DBVT_BP_PROFILING_RATE);
+ const unsigned long sum=m_profiling.m_ddcollide+
+ m_profiling.m_fdcollide+
+ m_profiling.m_cleanup;
+ printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE);
+ printf("job counts: %u%%\r\n",(m_profiling.m_jobcount*100)/((m_sets[0].m_leaves+m_sets[1].m_leaves)*DBVT_BP_PROFILING_RATE));
+ clear(m_profiling);
+ m_clock.reset();
}
#endif
+
+ performDeferredRemoval(dispatcher);
+
+}
+
+void btDbvtBroadphase::performDeferredRemoval(btDispatcher* dispatcher)
+{
+
+ if (m_paircache->hasDeferredRemoval())
+ {
+
+ btBroadphasePairArray& overlappingPairArray = m_paircache->getOverlappingPairArray();
+
+ //perform a sort, to find duplicates and to sort 'invalid' pairs to the end
+ overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
+
+ int invalidPair = 0;
+
+
+ int i;
+
+ btBroadphasePair previousPair;
+ previousPair.m_pProxy0 = 0;
+ previousPair.m_pProxy1 = 0;
+ previousPair.m_algorithm = 0;
+
+
+ for (i=0;i<overlappingPairArray.size();i++)
+ {
+
+ btBroadphasePair& pair = overlappingPairArray[i];
+
+ bool isDuplicate = (pair == previousPair);
+
+ previousPair = pair;
+
+ bool needsRemoval = false;
+
+ if (!isDuplicate)
+ {
+ //important to perform AABB check that is consistent with the broadphase
+ btDbvtProxy* pa=(btDbvtProxy*)pair.m_pProxy0;
+ btDbvtProxy* pb=(btDbvtProxy*)pair.m_pProxy1;
+ bool hasOverlap = Intersect(pa->leaf->volume,pb->leaf->volume);
+
+ if (hasOverlap)
+ {
+ needsRemoval = false;
+ } else
+ {
+ needsRemoval = true;
+ }
+ } else
+ {
+ //remove duplicate
+ needsRemoval = true;
+ //should have no algorithm
+ btAssert(!pair.m_algorithm);
+ }
+
+ if (needsRemoval)
+ {
+ m_paircache->cleanOverlappingPair(pair,dispatcher);
+
+ pair.m_pProxy0 = 0;
+ pair.m_pProxy1 = 0;
+ invalidPair++;
+ }
+
+ }
+
+ //perform a sort, to sort 'invalid' pairs to the end
+ overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
+ overlappingPairArray.resize(overlappingPairArray.size() - invalidPair);
+ }
}
//
void btDbvtBroadphase::collide(btDispatcher* dispatcher)
{
-SPC(m_profiling.m_total);
-/* optimize */
-m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100);
-if(m_fixedleft)
+ /*printf("---------------------------------------------------------\n");
+ printf("m_sets[0].m_leaves=%d\n",m_sets[0].m_leaves);
+ printf("m_sets[1].m_leaves=%d\n",m_sets[1].m_leaves);
+ printf("numPairs = %d\n",getOverlappingPairCache()->getNumOverlappingPairs());
{
- const int count=1+(m_sets[1].m_leaves*m_fupdates)/100;
- m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100);
- m_fixedleft=btMax<int>(0,m_fixedleft-count);
+ int i;
+ for (i=0;i<getOverlappingPairCache()->getNumOverlappingPairs();i++)
+ {
+ printf("pair[%d]=(%d,%d),",i,getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy0->getUid(),
+ getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy1->getUid());
+ }
+ printf("\n");
}
-/* dynamic -> fixed set */
-m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT;
-btDbvtProxy* current=m_stageRoots[m_stageCurrent];
-if(current)
+*/
+
+
+
+ SPC(m_profiling.m_total);
+ /* optimize */
+ m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100);
+ if(m_fixedleft)
+ {
+ const int count=1+(m_sets[1].m_leaves*m_fupdates)/100;
+ m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100);
+ m_fixedleft=btMax<int>(0,m_fixedleft-count);
+ }
+ /* dynamic -> fixed set */
+ m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT;
+ btDbvtProxy* current=m_stageRoots[m_stageCurrent];
+ if(current)
{
- btDbvtTreeCollider collider(this);
- do {
- btDbvtProxy* next=current->links[1];
- listremove(current,m_stageRoots[current->stage]);
- listappend(current,m_stageRoots[STAGECOUNT]);
- #if DBVT_BP_ACCURATESLEEPING
- m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher);
- collider.proxy=current;
- btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider);
- btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider);
- #endif
- m_sets[0].remove(current->leaf);
- current->leaf = m_sets[1].insert(current->aabb,current);
- current->stage = STAGECOUNT;
- current = next;
+ btDbvtTreeCollider collider(this);
+ do {
+ btDbvtProxy* next=current->links[1];
+ listremove(current,m_stageRoots[current->stage]);
+ listappend(current,m_stageRoots[STAGECOUNT]);
+#if DBVT_BP_ACCURATESLEEPING
+ m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher);
+ collider.proxy=current;
+ btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider);
+ btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider);
+#endif
+ m_sets[0].remove(current->leaf);
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) curAabb=btDbvtVolume::FromMM(current->m_aabbMin,current->m_aabbMax);
+ current->leaf = m_sets[1].insert(curAabb,current);
+ current->stage = STAGECOUNT;
+ current = next;
} while(current);
- m_fixedleft=m_sets[1].m_leaves;
- m_needcleanup=true;
+ m_fixedleft=m_sets[1].m_leaves;
+ m_needcleanup=true;
}
-/* collide dynamics */
+ /* collide dynamics */
{
- btDbvtTreeCollider collider(this);
- if(m_deferedcollide)
+ btDbvtTreeCollider collider(this);
+ if(m_deferedcollide)
{
- SPC(m_profiling.m_fdcollide);
- btDbvt::collideTT(m_sets[0].m_root,m_sets[1].m_root,collider);
+ SPC(m_profiling.m_fdcollide);
+ m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[1].m_root,collider);
}
- if(m_deferedcollide)
+ if(m_deferedcollide)
{
- SPC(m_profiling.m_ddcollide);
- btDbvt::collideTT(m_sets[0].m_root,m_sets[0].m_root,collider);
+ SPC(m_profiling.m_ddcollide);
+ m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[0].m_root,collider);
}
}
-/* clean up */
-if(m_needcleanup)
+ /* clean up */
+ if(m_needcleanup)
{
- SPC(m_profiling.m_cleanup);
- btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray();
- if(pairs.size()>0)
+ SPC(m_profiling.m_cleanup);
+ btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray();
+ if(pairs.size()>0)
{
- const int ci=pairs.size();
- int ni=btMin(ci,btMax<int>(m_newpairs,(ci*m_cupdates)/100));
- for(int i=0;i<ni;++i)
+
+ int ni=btMin(pairs.size(),btMax<int>(m_newpairs,(pairs.size()*m_cupdates)/100));
+ for(int i=0;i<ni;++i)
{
- btBroadphasePair& p=pairs[(m_cid+i)%ci];
- btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0;
- btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1;
- if(!Intersect(pa->leaf->volume,pb->leaf->volume))
+ btBroadphasePair& p=pairs[(m_cid+i)%pairs.size()];
+ btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0;
+ btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1;
+ if(!Intersect(pa->leaf->volume,pb->leaf->volume))
{
- #if DBVT_BP_SORTPAIRS
- if(pa>pb) btSwap(pa,pb);
- #endif
- m_paircache->removeOverlappingPair(pa,pb,dispatcher);
- --ni;--i;
+#if DBVT_BP_SORTPAIRS
+ if(pa->m_uniqueId>pb->m_uniqueId)
+ btSwap(pa,pb);
+#endif
+ m_paircache->removeOverlappingPair(pa,pb,dispatcher);
+ --ni;--i;
}
}
- if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0;
+ if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0;
}
}
-++m_pid;
-m_newpairs=1;
-m_needcleanup=false;
-if(m_updates_call>0)
+ ++m_pid;
+ m_newpairs=1;
+ m_needcleanup=false;
+ if(m_updates_call>0)
{ m_updates_ratio=m_updates_done/(btScalar)m_updates_call; }
else
{ m_updates_ratio=0; }
-m_updates_done/=2;
-m_updates_call/=2;
+ m_updates_done/=2;
+ m_updates_call/=2;
}
//
void btDbvtBroadphase::optimize()
{
-m_sets[0].optimizeTopDown();
-m_sets[1].optimizeTopDown();
+ m_sets[0].optimizeTopDown();
+ m_sets[1].optimizeTopDown();
}
//
btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache()
{
-return(m_paircache);
+ return(m_paircache);
}
//
const btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() const
{
-return(m_paircache);
+ return(m_paircache);
}
//
@@ -402,16 +547,49 @@ void btDbvtBroadphase::getBroadphaseAabb(btVector3& aabbMin,btVector3& aab
ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds;
-if(!m_sets[0].empty())
- if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume,
- m_sets[1].m_root->volume,bounds);
- else
- bounds=m_sets[0].m_root->volume;
-else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume;
- else
- bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0);
-aabbMin=bounds.Mins();
-aabbMax=bounds.Maxs();
+ if(!m_sets[0].empty())
+ if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume,
+ m_sets[1].m_root->volume,bounds);
+ else
+ bounds=m_sets[0].m_root->volume;
+ else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume;
+ else
+ bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0);
+ aabbMin=bounds.Mins();
+ aabbMax=bounds.Maxs();
+}
+
+void btDbvtBroadphase::resetPool(btDispatcher* dispatcher)
+{
+
+ int totalObjects = m_sets[0].m_leaves + m_sets[1].m_leaves;
+ if (!totalObjects)
+ {
+ //reset internal dynamic tree data structures
+ m_sets[0].clear();
+ m_sets[1].clear();
+
+ m_deferedcollide = false;
+ m_needcleanup = true;
+ m_prediction = 1/(btScalar)2;
+ m_stageCurrent = 0;
+ m_fixedleft = 0;
+ m_fupdates = 1;
+ m_dupdates = 0;
+ m_cupdates = 10;
+ m_newpairs = 1;
+ m_updates_call = 0;
+ m_updates_done = 0;
+ m_updates_ratio = 0;
+
+ m_gid = 0;
+ m_pid = 0;
+ m_cid = 0;
+ for(int i=0;i<=STAGECOUNT;++i)
+ {
+ m_stageRoots[i]=0;
+ }
+ }
}
//
@@ -422,9 +600,9 @@ void btDbvtBroadphase::printStats()
#if DBVT_BP_ENABLE_BENCHMARK
struct btBroadphaseBenchmark
- {
+{
struct Experiment
- {
+ {
const char* name;
int object_count;
int update_count;
@@ -432,109 +610,109 @@ struct btBroadphaseBenchmark
int iterations;
btScalar speed;
btScalar amplitude;
- };
+ };
struct Object
- {
+ {
btVector3 center;
btVector3 extents;
btBroadphaseProxy* proxy;
btScalar time;
void update(btScalar speed,btScalar amplitude,btBroadphaseInterface* pbi)
- {
+ {
time += speed;
center[0] = btCos(time*(btScalar)2.17)*amplitude+
- btSin(time)*amplitude/2;
+ btSin(time)*amplitude/2;
center[1] = btCos(time*(btScalar)1.38)*amplitude+
- btSin(time)*amplitude;
+ btSin(time)*amplitude;
center[2] = btSin(time*(btScalar)0.777)*amplitude;
pbi->setAabb(proxy,center-extents,center+extents,0);
- }
- };
+ }
+ };
static int UnsignedRand(int range=RAND_MAX-1) { return(rand()%(range+1)); }
static btScalar UnitRand() { return(UnsignedRand(16384)/(btScalar)16384); }
static void OutputTime(const char* name,btClock& c,unsigned count=0)
- {
+ {
const unsigned long us=c.getTimeMicroseconds();
const unsigned long ms=(us+500)/1000;
const btScalar sec=us/(btScalar)(1000*1000);
if(count>0)
printf("%s : %u us (%u ms), %.2f/s\r\n",name,us,ms,count/sec);
- else
+ else
printf("%s : %u us (%u ms)\r\n",name,us,ms);
- }
- };
+ }
+};
void btDbvtBroadphase::benchmark(btBroadphaseInterface* pbi)
{
-static const btBroadphaseBenchmark::Experiment experiments[]=
+ static const btBroadphaseBenchmark::Experiment experiments[]=
{
- {"1024o.10%",1024,10,0,8192,(btScalar)0.005,(btScalar)100},
- /*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100},
- {"8192o.10%",8192,10,0,8192,(btScalar)0.005,(btScalar)100},*/
+ {"1024o.10%",1024,10,0,8192,(btScalar)0.005,(btScalar)100},
+ /*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100},
+ {"8192o.10%",8192,10,0,8192,(btScalar)0.005,(btScalar)100},*/
};
-static const int nexperiments=sizeof(experiments)/sizeof(experiments[0]);
-btAlignedObjectArray<btBroadphaseBenchmark::Object*> objects;
-btClock wallclock;
-/* Begin */
-for(int iexp=0;iexp<nexperiments;++iexp)
+ static const int nexperiments=sizeof(experiments)/sizeof(experiments[0]);
+ btAlignedObjectArray<btBroadphaseBenchmark::Object*> objects;
+ btClock wallclock;
+ /* Begin */
+ for(int iexp=0;iexp<nexperiments;++iexp)
{
- const btBroadphaseBenchmark::Experiment& experiment=experiments[iexp];
- const int object_count=experiment.object_count;
- const int update_count=(object_count*experiment.update_count)/100;
- const int spawn_count=(object_count*experiment.spawn_count)/100;
- const btScalar speed=experiment.speed;
- const btScalar amplitude=experiment.amplitude;
- printf("Experiment #%u '%s':\r\n",iexp,experiment.name);
- printf("\tObjects: %u\r\n",object_count);
- printf("\tUpdate: %u\r\n",update_count);
- printf("\tSpawn: %u\r\n",spawn_count);
- printf("\tSpeed: %f\r\n",speed);
- printf("\tAmplitude: %f\r\n",amplitude);
- srand(180673);
- /* Create objects */
- wallclock.reset();
- objects.reserve(object_count);
- for(int i=0;i<object_count;++i)
+ const btBroadphaseBenchmark::Experiment& experiment=experiments[iexp];
+ const int object_count=experiment.object_count;
+ const int update_count=(object_count*experiment.update_count)/100;
+ const int spawn_count=(object_count*experiment.spawn_count)/100;
+ const btScalar speed=experiment.speed;
+ const btScalar amplitude=experiment.amplitude;
+ printf("Experiment #%u '%s':\r\n",iexp,experiment.name);
+ printf("\tObjects: %u\r\n",object_count);
+ printf("\tUpdate: %u\r\n",update_count);
+ printf("\tSpawn: %u\r\n",spawn_count);
+ printf("\tSpeed: %f\r\n",speed);
+ printf("\tAmplitude: %f\r\n",amplitude);
+ srand(180673);
+ /* Create objects */
+ wallclock.reset();
+ objects.reserve(object_count);
+ for(int i=0;i<object_count;++i)
{
- btBroadphaseBenchmark::Object* po=new btBroadphaseBenchmark::Object();
- po->center[0]=btBroadphaseBenchmark::UnitRand()*50;
- po->center[1]=btBroadphaseBenchmark::UnitRand()*50;
- po->center[2]=btBroadphaseBenchmark::UnitRand()*50;
- po->extents[0]=btBroadphaseBenchmark::UnitRand()*2+2;
- po->extents[1]=btBroadphaseBenchmark::UnitRand()*2+2;
- po->extents[2]=btBroadphaseBenchmark::UnitRand()*2+2;
- po->time=btBroadphaseBenchmark::UnitRand()*2000;
- po->proxy=pbi->createProxy(po->center-po->extents,po->center+po->extents,0,po,1,1,0,0);
- objects.push_back(po);
+ btBroadphaseBenchmark::Object* po=new btBroadphaseBenchmark::Object();
+ po->center[0]=btBroadphaseBenchmark::UnitRand()*50;
+ po->center[1]=btBroadphaseBenchmark::UnitRand()*50;
+ po->center[2]=btBroadphaseBenchmark::UnitRand()*50;
+ po->extents[0]=btBroadphaseBenchmark::UnitRand()*2+2;
+ po->extents[1]=btBroadphaseBenchmark::UnitRand()*2+2;
+ po->extents[2]=btBroadphaseBenchmark::UnitRand()*2+2;
+ po->time=btBroadphaseBenchmark::UnitRand()*2000;
+ po->proxy=pbi->createProxy(po->center-po->extents,po->center+po->extents,0,po,1,1,0,0);
+ objects.push_back(po);
}
- btBroadphaseBenchmark::OutputTime("\tInitialization",wallclock);
- /* First update */
- wallclock.reset();
- for(int i=0;i<objects.size();++i)
+ btBroadphaseBenchmark::OutputTime("\tInitialization",wallclock);
+ /* First update */
+ wallclock.reset();
+ for(int i=0;i<objects.size();++i)
{
- objects[i]->update(speed,amplitude,pbi);
+ objects[i]->update(speed,amplitude,pbi);
}
- btBroadphaseBenchmark::OutputTime("\tFirst update",wallclock);
- /* Updates */
- wallclock.reset();
- for(int i=0;i<experiment.iterations;++i)
+ btBroadphaseBenchmark::OutputTime("\tFirst update",wallclock);
+ /* Updates */
+ wallclock.reset();
+ for(int i=0;i<experiment.iterations;++i)
{
- for(int j=0;j<update_count;++j)
+ for(int j=0;j<update_count;++j)
{
- objects[j]->update(speed,amplitude,pbi);
+ objects[j]->update(speed,amplitude,pbi);
}
- pbi->calculateOverlappingPairs(0);
+ pbi->calculateOverlappingPairs(0);
}
- btBroadphaseBenchmark::OutputTime("\tUpdate",wallclock,experiment.iterations);
- /* Clean up */
- wallclock.reset();
- for(int i=0;i<objects.size();++i)
+ btBroadphaseBenchmark::OutputTime("\tUpdate",wallclock,experiment.iterations);
+ /* Clean up */
+ wallclock.reset();
+ for(int i=0;i<objects.size();++i)
{
- pbi->destroyProxy(objects[i]->proxy,0);
- delete objects[i];
+ pbi->destroyProxy(objects[i]->proxy,0);
+ delete objects[i];
}
- objects.resize(0);
- btBroadphaseBenchmark::OutputTime("\tRelease",wallclock);
+ objects.resize(0);
+ btBroadphaseBenchmark::OutputTime("\tRelease",wallclock);
}
}
@@ -546,3 +724,4 @@ void btDbvtBroadphase::benchmark(btBroadphaseInterface*)
#if DBVT_BP_PROFILE
#undef SPC
#endif
+
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h
index 1f16043a7a8..fe70bc39c43 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h
@@ -24,15 +24,15 @@ subject to the following restrictions:
//
#define DBVT_BP_PROFILE 0
-#define DBVT_BP_SORTPAIRS 1
+//#define DBVT_BP_SORTPAIRS 1
#define DBVT_BP_PREVENTFALSEUPDATE 0
#define DBVT_BP_ACCURATESLEEPING 0
#define DBVT_BP_ENABLE_BENCHMARK 0
#define DBVT_BP_MARGIN (btScalar)0.05
#if DBVT_BP_PROFILE
- #define DBVT_BP_PROFILING_RATE 256
- #include "LinearMath/btQuickprof.h"
+#define DBVT_BP_PROFILING_RATE 256
+#include "LinearMath/btQuickprof.h"
#endif
//
@@ -40,16 +40,16 @@ subject to the following restrictions:
//
struct btDbvtProxy : btBroadphaseProxy
{
-/* Fields */
-btDbvtAabbMm aabb;
-btDbvtNode* leaf;
-btDbvtProxy* links[2];
-int stage;
-/* ctor */
-btDbvtProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) :
- btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask)
+ /* Fields */
+ //btDbvtAabbMm aabb;
+ btDbvtNode* leaf;
+ btDbvtProxy* links[2];
+ int stage;
+ /* ctor */
+ btDbvtProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) :
+ btBroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask)
{
- links[0]=links[1]=0;
+ links[0]=links[1]=0;
}
};
@@ -60,57 +60,67 @@ typedef btAlignedObjectArray<btDbvtProxy*> btDbvtProxyArray;
///This is a very fast broadphase, especially for very dynamic worlds where many objects are moving. Its insert/add and remove of objects is generally faster than the sweep and prune broadphases btAxisSweep3 and bt32BitAxisSweep3.
struct btDbvtBroadphase : btBroadphaseInterface
{
-/* Config */
-enum {
+ /* Config */
+ enum {
DYNAMIC_SET = 0, /* Dynamic set index */
FIXED_SET = 1, /* Fixed set index */
STAGECOUNT = 2 /* Number of stages */
- };
-/* Fields */
-btDbvt m_sets[2]; // Dbvt sets
-btDbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list
-btOverlappingPairCache* m_paircache; // Pair cache
-btScalar m_prediction; // Velocity prediction
-int m_stageCurrent; // Current stage
-int m_fupdates; // % of fixed updates per frame
-int m_dupdates; // % of dynamic updates per frame
-int m_cupdates; // % of cleanup updates per frame
-int m_newpairs; // Number of pairs created
-int m_fixedleft; // Fixed optimization left
-unsigned m_updates_call; // Number of updates call
-unsigned m_updates_done; // Number of updates done
-btScalar m_updates_ratio; // m_updates_done/m_updates_call
-int m_pid; // Parse id
-int m_cid; // Cleanup index
-int m_gid; // Gen id
-bool m_releasepaircache; // Release pair cache on delete
-bool m_deferedcollide; // Defere dynamic/static collision to collide call
-bool m_needcleanup; // Need to run cleanup?
+ };
+ /* Fields */
+ btDbvt m_sets[2]; // Dbvt sets
+ btDbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list
+ btOverlappingPairCache* m_paircache; // Pair cache
+ btScalar m_prediction; // Velocity prediction
+ int m_stageCurrent; // Current stage
+ int m_fupdates; // % of fixed updates per frame
+ int m_dupdates; // % of dynamic updates per frame
+ int m_cupdates; // % of cleanup updates per frame
+ int m_newpairs; // Number of pairs created
+ int m_fixedleft; // Fixed optimization left
+ unsigned m_updates_call; // Number of updates call
+ unsigned m_updates_done; // Number of updates done
+ btScalar m_updates_ratio; // m_updates_done/m_updates_call
+ int m_pid; // Parse id
+ int m_cid; // Cleanup index
+ int m_gid; // Gen id
+ bool m_releasepaircache; // Release pair cache on delete
+ bool m_deferedcollide; // Defere dynamic/static collision to collide call
+ bool m_needcleanup; // Need to run cleanup?
#if DBVT_BP_PROFILE
-btClock m_clock;
-struct {
+ btClock m_clock;
+ struct {
unsigned long m_total;
unsigned long m_ddcollide;
unsigned long m_fdcollide;
unsigned long m_cleanup;
unsigned long m_jobcount;
- } m_profiling;
+ } m_profiling;
#endif
-/* Methods */
-btDbvtBroadphase(btOverlappingPairCache* paircache=0);
-~btDbvtBroadphase();
-void collide(btDispatcher* dispatcher);
-void optimize();
-/* btBroadphaseInterface Implementation */
-btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
-void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
-void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
-void calculateOverlappingPairs(btDispatcher* dispatcher);
-btOverlappingPairCache* getOverlappingPairCache();
-const btOverlappingPairCache* getOverlappingPairCache() const;
-void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
-void printStats();
-static void benchmark(btBroadphaseInterface*);
+ /* Methods */
+ btDbvtBroadphase(btOverlappingPairCache* paircache=0);
+ ~btDbvtBroadphase();
+ void collide(btDispatcher* dispatcher);
+ void optimize();
+ /* btBroadphaseInterface Implementation */
+ btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
+ void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+ void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
+ virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
+
+ virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
+ void calculateOverlappingPairs(btDispatcher* dispatcher);
+ btOverlappingPairCache* getOverlappingPairCache();
+ const btOverlappingPairCache* getOverlappingPairCache() const;
+ void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
+ void printStats();
+ static void benchmark(btBroadphaseInterface*);
+
+
+ void performDeferredRemoval(btDispatcher* dispatcher);
+
+ ///reset broadphase internal structures, to ensure determinism/reproducability
+ virtual void resetPool(btDispatcher* dispatcher);
+
};
#endif
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h
index 6db71a0170e..ee57aa96151 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h
@@ -46,22 +46,25 @@ struct btDispatcherInfo
m_enableSPU(true),
m_useEpa(true),
m_allowedCcdPenetration(btScalar(0.04)),
+ m_useConvexConservativeDistanceUtil(true),
+ m_convexConservativeDistanceThreshold(0.0f),
m_stackAllocator(0)
{
}
btScalar m_timeStep;
- int m_stepCount;
- int m_dispatchFunc;
+ int m_stepCount;
+ int m_dispatchFunc;
mutable btScalar m_timeOfImpact;
- bool m_useContinuous;
+ bool m_useContinuous;
class btIDebugDraw* m_debugDraw;
- bool m_enableSatConvex;
- bool m_enableSPU;
- bool m_useEpa;
+ bool m_enableSatConvex;
+ bool m_enableSPU;
+ bool m_useEpa;
btScalar m_allowedCcdPenetration;
+ bool m_useConvexConservativeDistanceUtil;
+ btScalar m_convexConservativeDistanceThreshold;
btStackAlloc* m_stackAllocator;
-
};
///The btDispatcher interface class can be used in combination with broadphase to dispatch calculations for overlapping pairs.
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp
index 3f866ab7c5f..6712f528e97 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp
@@ -149,6 +149,22 @@ amin.getZ() >= bmin.getZ() && amax.getZ() <= bmax.getZ();
+void btMultiSapBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+ btMultiSapProxy* multiProxy = static_cast<btMultiSapProxy*>(proxy);
+ aabbMin = multiProxy->m_aabbMin;
+ aabbMax = multiProxy->m_aabbMax;
+}
+
+void btMultiSapBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin,const btVector3& aabbMax)
+{
+ for (int i=0;i<m_multiSapProxies.size();i++)
+ {
+ rayCallback.process(m_multiSapProxies[i]);
+ }
+}
+
+
//#include <stdio.h>
void btMultiSapBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)
@@ -208,7 +224,9 @@ void btMultiSapBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aab
- m_optimizedAabbTree->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
+ if (m_optimizedAabbTree)
+ m_optimizedAabbTree->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
+
int i;
for ( i=0;i<multiProxy->m_bridgeProxies.size();i++)
@@ -464,3 +482,8 @@ void btMultiSapBroadphase::printStats()
*/
}
+
+void btMultiSapBroadphase::resetPool(btDispatcher* dispatcher)
+{
+ // not yet
+}
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h
index a0c002de856..91c504eee22 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h
@@ -26,6 +26,7 @@ class btSimpleBroadphase;
typedef btAlignedObjectArray<btBroadphaseInterface*> btSapBroadphaseArray;
+///The btMultiSapBroadphase is a research project, not recommended to use in production. Use btAxisSweep3 or btDbvtBroadphase instead.
///The btMultiSapBroadphase is a broadphase that contains multiple SAP broadphases.
///The user can add SAP broadphases that cover the world. A btBroadphaseProxy can be in multiple child broadphases at the same time.
///A btQuantizedBvh acceleration structures finds overlapping SAPs for each btBroadphaseProxy.
@@ -72,7 +73,7 @@ public:
short int m_collisionFilterMask;
*/
btMultiSapProxy(const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask)
- :btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask),
+ :btBroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask),
m_aabbMin(aabbMin),
m_aabbMax(aabbMax),
m_shapeType(shapeType)
@@ -108,6 +109,9 @@ public:
virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy);
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher);
+ virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
+
+ virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0));
void addToChildBroadphase(btMultiSapProxy* parentMultiSapProxy, btBroadphaseProxy* childProxy, btBroadphaseInterface* childBroadphase);
@@ -139,6 +143,9 @@ public:
void quicksort (btBroadphasePairArray& a, int lo, int hi);
+ ///reset broadphase internal structures, to ensure determinism/reproducability
+ virtual void resetPool(btDispatcher* dispatcher);
+
};
#endif //BT_MULTI_SAP_BROADPHASE
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
index ff65cdde79f..b209bcb9a20 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
@@ -19,6 +19,7 @@ subject to the following restrictions:
#include "btDispatcher.h"
#include "btCollisionAlgorithm.h"
+#include "LinearMath/btAabbUtil2.h"
#include <stdio.h>
@@ -33,7 +34,8 @@ int gFindPairs =0;
btHashedOverlappingPairCache::btHashedOverlappingPairCache():
m_overlapFilterCallback(0),
- m_blockedForChanges(false)
+ m_blockedForChanges(false),
+ m_ghostPairCallback(0)
{
int initialAllocatedSize= 2;
m_overlappingPairArray.reserve(initialAllocatedSize);
@@ -45,7 +47,6 @@ btHashedOverlappingPairCache::btHashedOverlappingPairCache():
btHashedOverlappingPairCache::~btHashedOverlappingPairCache()
{
- //todo/test: show we erase/delete data, or is it automatic
}
@@ -135,7 +136,8 @@ void btHashedOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroad
btBroadphasePair* btHashedOverlappingPairCache::findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
{
gFindPairs++;
- if(proxy0>proxy1) btSwap(proxy0,proxy1);
+ if(proxy0->m_uniqueId>proxy1->m_uniqueId)
+ btSwap(proxy0,proxy1);
int proxyId1 = proxy0->getUid();
int proxyId2 = proxy1->getUid();
@@ -211,7 +213,8 @@ void btHashedOverlappingPairCache::growTables()
btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
{
- if(proxy0>proxy1) btSwap(proxy0,proxy1);
+ if(proxy0->m_uniqueId>proxy1->m_uniqueId)
+ btSwap(proxy0,proxy1);
int proxyId1 = proxy0->getUid();
int proxyId2 = proxy1->getUid();
@@ -238,6 +241,11 @@ btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProx
int count = m_overlappingPairArray.size();
int oldCapacity = m_overlappingPairArray.capacity();
void* mem = &m_overlappingPairArray.expand();
+
+ //this is where we add an actual pair, so also call the 'ghost'
+ if (m_ghostPairCallback)
+ m_ghostPairCallback->addOverlappingPair(proxy0,proxy1);
+
int newCapacity = m_overlappingPairArray.capacity();
if (oldCapacity < newCapacity)
@@ -251,7 +259,7 @@ btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProx
// pair->m_pProxy0 = proxy0;
// pair->m_pProxy1 = proxy1;
pair->m_algorithm = 0;
- pair->m_userInfo = 0;
+ pair->m_internalTmpValue = 0;
m_next[count] = m_hashTable[hash];
@@ -265,7 +273,8 @@ btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProx
void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1,btDispatcher* dispatcher)
{
gRemovePairs++;
- if(proxy0>proxy1) btSwap(proxy0,proxy1);
+ if(proxy0->m_uniqueId>proxy1->m_uniqueId)
+ btSwap(proxy0,proxy1);
int proxyId1 = proxy0->getUid();
int proxyId2 = proxy1->getUid();
@@ -282,7 +291,7 @@ void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* pro
cleanOverlappingPair(*pair,dispatcher);
- void* userData = pair->m_userInfo;
+ void* userData = pair->m_internalInfo1;
btAssert(pair->m_pProxy0->getUid() == proxyId1);
btAssert(pair->m_pProxy1->getUid() == proxyId2);
@@ -317,6 +326,9 @@ void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* pro
int lastPairIndex = m_overlappingPairArray.size() - 1;
+ if (m_ghostPairCallback)
+ m_ghostPairCallback->removeOverlappingPair(proxy0, proxy1,dispatcher);
+
// If the removed pair is the last pair, we are done.
if (lastPairIndex == pairIndex)
{
@@ -384,6 +396,35 @@ void btHashedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback*
}
}
+void btHashedOverlappingPairCache::sortOverlappingPairs(btDispatcher* dispatcher)
+{
+ ///need to keep hashmap in sync with pair address, so rebuild all
+ btBroadphasePairArray tmpPairs;
+ int i;
+ for (i=0;i<m_overlappingPairArray.size();i++)
+ {
+ tmpPairs.push_back(m_overlappingPairArray[i]);
+ }
+
+ for (i=0;i<tmpPairs.size();i++)
+ {
+ removeOverlappingPair(tmpPairs[i].m_pProxy0,tmpPairs[i].m_pProxy1,dispatcher);
+ }
+
+ for (i = 0; i < m_next.size(); i++)
+ {
+ m_next[i] = BT_NULL_PAIR;
+ }
+
+ tmpPairs.quickSort(btBroadphasePairSortPredicate());
+
+ for (i=0;i<tmpPairs.size();i++)
+ {
+ addOverlappingPair(tmpPairs[i].m_pProxy0,tmpPairs[i].m_pProxy1);
+ }
+
+
+}
void* btSortedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1, btDispatcher* dispatcher )
@@ -397,8 +438,10 @@ void* btSortedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* pro
{
gOverlappingPairs--;
btBroadphasePair& pair = m_overlappingPairArray[findIndex];
- void* userData = pair.m_userInfo;
+ void* userData = pair.m_internalInfo1;
cleanOverlappingPair(pair,dispatcher);
+ if (m_ghostPairCallback)
+ m_ghostPairCallback->removeOverlappingPair(proxy0, proxy1,dispatcher);
m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.capacity()-1);
m_overlappingPairArray.pop_back();
@@ -419,15 +462,19 @@ void* btSortedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* pro
btBroadphasePair* btSortedOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
{
//don't add overlap with own
- assert(proxy0 != proxy1);
+ btAssert(proxy0 != proxy1);
if (!needsBroadphaseCollision(proxy0,proxy1))
return 0;
void* mem = &m_overlappingPairArray.expand();
btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1);
+
gOverlappingPairs++;
gAddedPairs++;
+
+ if (m_ghostPairCallback)
+ m_ghostPairCallback->addOverlappingPair(proxy0, proxy1);
return pair;
}
@@ -446,7 +493,7 @@ btBroadphasePair* btSortedOverlappingPairCache::addOverlappingPair(btBroadphaseP
if (findIndex < m_overlappingPairArray.size())
{
- //assert(it != m_overlappingPairSet.end());
+ //btAssert(it != m_overlappingPairSet.end());
btBroadphasePair* pair = &m_overlappingPairArray[findIndex];
return pair;
}
@@ -476,8 +523,9 @@ void btSortedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback*
if (callback->processOverlap(*pair))
{
cleanOverlappingPair(*pair,dispatcher);
-
- m_overlappingPairArray.swap(i,m_overlappingPairArray.capacity()-1);
+ pair->m_pProxy0 = 0;
+ pair->m_pProxy1 = 0;
+ m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
m_overlappingPairArray.pop_back();
gOverlappingPairs--;
} else
@@ -493,7 +541,8 @@ void btSortedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback*
btSortedOverlappingPairCache::btSortedOverlappingPairCache():
m_blockedForChanges(false),
m_hasDeferredRemoval(true),
- m_overlapFilterCallback(0)
+ m_overlapFilterCallback(0),
+ m_ghostPairCallback(0)
{
int initialAllocatedSize= 2;
m_overlappingPairArray.reserve(initialAllocatedSize);
@@ -501,7 +550,6 @@ btSortedOverlappingPairCache::btSortedOverlappingPairCache():
btSortedOverlappingPairCache::~btSortedOverlappingPairCache()
{
- //todo/test: show we erase/delete data, or is it automatic
}
void btSortedOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher)
@@ -577,3 +625,9 @@ void btSortedOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroad
processAllOverlappingPairs(&removeCallback,dispatcher);
}
+
+void btSortedOverlappingPairCache::sortOverlappingPairs(btDispatcher* dispatcher)
+{
+ //should already be sorted
+}
+
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
index 66679bd218a..eda45c47b5b 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
@@ -21,7 +21,6 @@ subject to the following restrictions:
#include "btBroadphaseProxy.h"
#include "btOverlappingPairCallback.h"
-#include "LinearMath/btPoint3.h"
#include "LinearMath/btAlignedObjectArray.h"
class btDispatcher;
@@ -83,6 +82,11 @@ public:
virtual bool hasDeferredRemoval() = 0;
+ virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)=0;
+
+ virtual void sortOverlappingPairs(btDispatcher* dispatcher) = 0;
+
+
};
/// Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman, Codercorner, http://codercorner.com
@@ -253,10 +257,19 @@ private:
return false;
}
-public:
+ virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)
+ {
+ m_ghostPairCallback = ghostPairCallback;
+ }
+
+ virtual void sortOverlappingPairs(btDispatcher* dispatcher);
+
+
+protected:
btAlignedObjectArray<int> m_hashTable;
btAlignedObjectArray<int> m_next;
+ btOverlappingPairCallback* m_ghostPairCallback;
};
@@ -280,6 +293,8 @@ class btSortedOverlappingPairCache : public btOverlappingPairCache
//if set, use the callback instead of the built in filter in needBroadphaseCollision
btOverlapFilterCallback* m_overlapFilterCallback;
+ btOverlappingPairCallback* m_ghostPairCallback;
+
public:
btSortedOverlappingPairCache();
@@ -355,12 +370,19 @@ class btSortedOverlappingPairCache : public btOverlappingPairCache
return m_hasDeferredRemoval;
}
+ virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)
+ {
+ m_ghostPairCallback = ghostPairCallback;
+ }
+
+ virtual void sortOverlappingPairs(btDispatcher* dispatcher);
+
};
-///btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and testing.
+///btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing.
class btNullPairCache : public btOverlappingPairCache
{
@@ -414,6 +436,11 @@ public:
return true;
}
+ virtual void setInternalGhostPairCallback(btOverlappingPairCallback* /* ghostPairCallback */)
+ {
+
+ }
+
virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/)
{
return 0;
@@ -427,6 +454,10 @@ public:
virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/,btDispatcher* /*dispatcher*/)
{
}
+
+ virtual void sortOverlappingPairs(btDispatcher* dispatcher)
+ {
+ }
};
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
index a30bd1fd9e1..8bef8f0d43e 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
@@ -18,14 +18,18 @@ subject to the following restrictions:
#include "LinearMath/btAabbUtil2.h"
#include "LinearMath/btIDebugDraw.h"
+#define RAYAABB2
-btQuantizedBvh::btQuantizedBvh() : m_useQuantization(false),
+btQuantizedBvh::btQuantizedBvh() :
+ m_bulletVersion(BT_BULLET_VERSION),
+ m_useQuantization(false),
//m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY)
m_traversalMode(TRAVERSAL_STACKLESS)
//m_traversalMode(TRAVERSAL_RECURSIVE)
,m_subtreeHeaderCount(0) //PCK: add this line
-{
-
+{
+ m_bvhAabbMin.setValue(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY);
+ m_bvhAabbMax.setValue(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY);
}
@@ -119,7 +123,7 @@ void btQuantizedBvh::buildTree (int startIndex,int endIndex)
int numIndices =endIndex-startIndex;
int curIndex = m_curNodeIndex;
- assert(numIndices>0);
+ btAssert(numIndices>0);
if (numIndices==1)
{
@@ -140,8 +144,11 @@ void btQuantizedBvh::buildTree (int startIndex,int endIndex)
int internalNodeIndex = m_curNodeIndex;
- setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);
- setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);
+ //set the min aabb to 'inf' or a max value, and set the max aabb to a -inf/minimum value.
+ //the aabb will be expanded during buildTree/mergeInternalNodeAabb with actual node values
+ setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);//can't use btVector3(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY)) because of quantization
+ setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);//can't use btVector3(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY)) because of quantization
+
for (i=startIndex;i<endIndex;i++)
{
@@ -177,6 +184,9 @@ void btQuantizedBvh::buildTree (int startIndex,int endIndex)
{
updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex);
}
+ } else
+ {
+
}
setInternalNodeEscapeIndex(internalNodeIndex,escapeIndex);
@@ -338,6 +348,7 @@ void btQuantizedBvh::reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallb
int maxIterations = 0;
+
void btQuantizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
{
btAssert(!m_useQuantization);
@@ -352,7 +363,7 @@ void btQuantizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const
while (curIndex < m_curNodeIndex)
{
//catch bugs in tree data
- assert (walkIterations < m_curNodeIndex);
+ btAssert (walkIterations < m_curNodeIndex);
walkIterations++;
aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
@@ -434,6 +445,96 @@ void btQuantizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantize
+void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const
+{
+ btAssert(!m_useQuantization);
+
+ const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];
+ int escapeIndex, curIndex = 0;
+ int walkIterations = 0;
+ bool isLeafNode;
+ //PCK: unsigned instead of bool
+ unsigned aabbOverlap=0;
+ unsigned rayBoxOverlap=0;
+ btScalar lambda_max = 1.0;
+
+ /* Quick pruning by quantized box */
+ btVector3 rayAabbMin = raySource;
+ btVector3 rayAabbMax = raySource;
+ rayAabbMin.setMin(rayTarget);
+ rayAabbMax.setMax(rayTarget);
+
+ /* Add box cast extents to bounding box */
+ rayAabbMin += aabbMin;
+ rayAabbMax += aabbMax;
+
+#ifdef RAYAABB2
+ btVector3 rayDir = (rayTarget-raySource);
+ rayDir.normalize ();
+ lambda_max = rayDir.dot(rayTarget-raySource);
+ ///what about division by zero? --> just set rayDirection[i] to 1.0
+ btVector3 rayDirectionInverse;
+ rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
+ rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
+ rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+ unsigned int sign[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
+#endif
+
+ btVector3 bounds[2];
+
+ while (curIndex < m_curNodeIndex)
+ {
+ btScalar param = 1.0;
+ //catch bugs in tree data
+ btAssert (walkIterations < m_curNodeIndex);
+
+ walkIterations++;
+
+ bounds[0] = rootNode->m_aabbMinOrg;
+ bounds[1] = rootNode->m_aabbMaxOrg;
+ /* Add box cast extents */
+ bounds[0] += aabbMin;
+ bounds[1] += aabbMax;
+
+ aabbOverlap = TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
+ //perhaps profile if it is worth doing the aabbOverlap test first
+
+#ifdef RAYAABB2
+ ///careful with this check: need to check division by zero (above) and fix the unQuantize method
+ ///thanks Joerg/hiker for the reproduction case!
+ ///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858
+ rayBoxOverlap = aabbOverlap ? btRayAabb2 (raySource, rayDirectionInverse, sign, bounds, param, 0.0f, lambda_max) : false;
+
+#else
+ btVector3 normal;
+ rayBoxOverlap = btRayAabb(raySource, rayTarget,bounds[0],bounds[1],param, normal);
+#endif
+
+ isLeafNode = rootNode->m_escapeIndex == -1;
+
+ //PCK: unsigned instead of bool
+ if (isLeafNode && (rayBoxOverlap != 0))
+ {
+ nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
+ }
+
+ //PCK: unsigned instead of bool
+ if ((rayBoxOverlap != 0) || isLeafNode)
+ {
+ rootNode++;
+ curIndex++;
+ } else
+ {
+ escapeIndex = rootNode->m_escapeIndex;
+ rootNode += escapeIndex;
+ curIndex += escapeIndex;
+ }
+ }
+ if (maxIterations < walkIterations)
+ maxIterations = walkIterations;
+
+}
+
void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const
@@ -454,9 +555,8 @@ void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback*
unsigned rayBoxOverlap = 0;
btScalar lambda_max = 1.0;
-#define RAYAABB2
+
#ifdef RAYAABB2
- btVector3 rayFrom = raySource;
btVector3 rayDirection = (rayTarget-raySource);
rayDirection.normalize ();
lambda_max = rayDirection.dot(rayTarget-raySource);
@@ -502,7 +602,7 @@ void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback*
#endif//VISUALLY_ANALYZE_BVH
//catch bugs in tree data
- assert (walkIterations < subTreeSize);
+ btAssert (walkIterations < subTreeSize);
walkIterations++;
//PCK: unsigned instead of bool
@@ -533,7 +633,9 @@ void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback*
///thanks Joerg/hiker for the reproduction case!
///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858
+ //BT_PROFILE("btRayAabb2");
rayBoxOverlap = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0f, lambda_max);
+
#else
rayBoxOverlap = true;//btRayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal);
#endif
@@ -597,7 +699,7 @@ void btQuantizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallb
#endif//VISUALLY_ANALYZE_BVH
//catch bugs in tree data
- assert (walkIterations < subTreeSize);
+ btAssert (walkIterations < subTreeSize);
walkIterations++;
//PCK: unsigned instead of bool
@@ -652,30 +754,25 @@ void btQuantizedBvh::walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallba
void btQuantizedBvh::reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const
{
- bool fast_path = m_useQuantization && m_traversalMode == TRAVERSAL_STACKLESS;
- if (fast_path)
- {
- walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, btVector3(0, 0, 0), btVector3(0, 0, 0), 0, m_curNodeIndex);
- } else {
- /* Otherwise fallback to AABB overlap test */
- btVector3 aabbMin = raySource;
- btVector3 aabbMax = raySource;
- aabbMin.setMin(rayTarget);
- aabbMax.setMax(rayTarget);
- reportAabbOverlappingNodex(nodeCallback,aabbMin,aabbMax);
- }
+ reportBoxCastOverlappingNodex(nodeCallback,raySource,rayTarget,btVector3(0,0,0),btVector3(0,0,0));
}
void btQuantizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const
{
- bool fast_path = m_useQuantization && m_traversalMode == TRAVERSAL_STACKLESS;
- if (fast_path)
+ //always use stackless
+
+ if (m_useQuantization)
{
walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex);
- } else {
- /* Slow path:
- Construct the bounding box for the entire box cast and send that down the tree */
+ }
+ else
+ {
+ walkStacklessTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex);
+ }
+ /*
+ {
+ //recursive traversal
btVector3 qaabbMin = raySource;
btVector3 qaabbMax = raySource;
qaabbMin.setMin(rayTarget);
@@ -684,6 +781,8 @@ void btQuantizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCa
qaabbMax += aabbMax;
reportAabbOverlappingNodex(nodeCallback,qaabbMin,qaabbMax);
}
+ */
+
}
@@ -716,17 +815,19 @@ void btQuantizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNod
//PCK: include
#include <new>
+#if 0
//PCK: consts
static const unsigned BVH_ALIGNMENT = 16;
static const unsigned BVH_ALIGNMENT_MASK = BVH_ALIGNMENT-1;
static const unsigned BVH_ALIGNMENT_BLOCKS = 2;
-
+#endif
unsigned int btQuantizedBvh::getAlignmentSerializationPadding()
{
- return BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT;
+ // I changed this to 0 since the extra padding is not needed or used.
+ return 0;//BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT;
}
unsigned btQuantizedBvh::calculateSerializeBufferSize()
@@ -742,7 +843,7 @@ unsigned btQuantizedBvh::calculateSerializeBufferSize()
bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian)
{
- assert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
+ btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
m_subtreeHeaderCount = m_SubtreeHeaders.size();
/* if (i_dataBufferSize < calculateSerializeBufferSize() || o_alignedDataBuffer == NULL || (((unsigned)o_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0))
@@ -829,6 +930,11 @@ bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe
}
}
nodeData += sizeof(btQuantizedBvhNode) * nodeCount;
+
+ // this clears the pointer in the member variable it doesn't really do anything to the data
+ // it does call the destructor on the contained objects, but they are all classes with no destructor defined
+ // so the memory (which is not freed) is left alone
+ targetBvh->m_quantizedContiguousNodes.initializeFromBuffer(NULL, 0, 0);
}
else
{
@@ -859,6 +965,11 @@ bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe
}
}
nodeData += sizeof(btOptimizedBvhNode) * nodeCount;
+
+ // this clears the pointer in the member variable it doesn't really do anything to the data
+ // it does call the destructor on the contained objects, but they are all classes with no destructor defined
+ // so the memory (which is not freed) is left alone
+ targetBvh->m_contiguousNodes.initializeFromBuffer(NULL, 0, 0);
}
sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
@@ -896,12 +1007,23 @@ bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe
targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = (m_SubtreeHeaders[i].m_rootNodeIndex);
targetBvh->m_SubtreeHeaders[i].m_subtreeSize = (m_SubtreeHeaders[i].m_subtreeSize);
- targetBvh->m_SubtreeHeaders[i] = m_SubtreeHeaders[i];
+
+ // need to clear padding in destination buffer
+ targetBvh->m_SubtreeHeaders[i].m_padding[0] = 0;
+ targetBvh->m_SubtreeHeaders[i].m_padding[1] = 0;
+ targetBvh->m_SubtreeHeaders[i].m_padding[2] = 0;
}
}
-
nodeData += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount;
+ // this clears the pointer in the member variable it doesn't really do anything to the data
+ // it does call the destructor on the contained objects, but they are all classes with no destructor defined
+ // so the memory (which is not freed) is left alone
+ targetBvh->m_SubtreeHeaders.initializeFromBuffer(NULL, 0, 0);
+
+ // this wipes the virtual function table pointer at the start of the buffer for the class
+ *((void**)o_alignedDataBuffer) = NULL;
+
return true;
}
@@ -1015,11 +1137,12 @@ btQuantizedBvh *btQuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, un
btQuantizedBvh::btQuantizedBvh(btQuantizedBvh &self, bool /* ownsMemory */) :
m_bvhAabbMin(self.m_bvhAabbMin),
m_bvhAabbMax(self.m_bvhAabbMax),
-m_bvhQuantization(self.m_bvhQuantization)
+m_bvhQuantization(self.m_bvhQuantization),
+m_bulletVersion(BT_BULLET_VERSION)
{
-
}
+
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h
index 8a149b533fa..ced457b6036 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h
@@ -158,41 +158,43 @@ typedef btAlignedObjectArray<btBvhSubtreeInfo> BvhSubtreeInfoArray;
///It is recommended to use quantization for better performance and lower memory requirements.
ATTRIBUTE_ALIGNED16(class) btQuantizedBvh
{
-protected:
-
- NodeArray m_leafNodes;
- NodeArray m_contiguousNodes;
-
- QuantizedNodeArray m_quantizedLeafNodes;
-
- QuantizedNodeArray m_quantizedContiguousNodes;
-
- int m_curNodeIndex;
-
-
- //quantization data
- bool m_useQuantization;
- btVector3 m_bvhAabbMin;
- btVector3 m_bvhAabbMax;
- btVector3 m_bvhQuantization;
public:
- BT_DECLARE_ALIGNED_ALLOCATOR();
-
enum btTraversalMode
{
TRAVERSAL_STACKLESS = 0,
TRAVERSAL_STACKLESS_CACHE_FRIENDLY,
TRAVERSAL_RECURSIVE
};
+
protected:
- btTraversalMode m_traversalMode;
+
+ btVector3 m_bvhAabbMin;
+ btVector3 m_bvhAabbMax;
+ btVector3 m_bvhQuantization;
+
+ int m_bulletVersion; //for serialization versioning. It could also be used to detect endianess.
+
+ int m_curNodeIndex;
+ //quantization data
+ bool m_useQuantization;
+
+
+
+ NodeArray m_leafNodes;
+ NodeArray m_contiguousNodes;
+ QuantizedNodeArray m_quantizedLeafNodes;
+ QuantizedNodeArray m_quantizedContiguousNodes;
+ btTraversalMode m_traversalMode;
BvhSubtreeInfoArray m_SubtreeHeaders;
//This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray
int m_subtreeHeaderCount;
+
+
+
///two versions, one for quantized and normal nodes. This allows code-reuse while maintaining readability (no template/macro!)
///this might be refactored into a virtual, it is usually not calculated at run-time
@@ -296,6 +298,7 @@ protected:
void walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const;
void walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const;
+ void walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const;
///tree traversal designed for small-memory processors like PS3 SPU
void walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const;
@@ -307,30 +310,14 @@ protected:
void walkRecursiveQuantizedTreeAgainstQuantizedTree(const btQuantizedBvhNode* treeNodeA,const btQuantizedBvhNode* treeNodeB,btNodeOverlapCallback* nodeCallback) const;
-#define USE_BANCHLESS 1
-#ifdef USE_BANCHLESS
- //This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360)
- SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const
- {
- return static_cast<unsigned int>(btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0])
- & (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2])
- & (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])),
- 1, 0));
- }
-#else
- SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const
- {
- bool overlap = true;
- overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
- overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
- overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
- return overlap;
- }
-#endif //USE_BANCHLESS
+
void updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex);
public:
+
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btQuantizedBvh();
virtual ~btQuantizedBvh();
@@ -363,7 +350,7 @@ public:
btVector3 v = (point - m_bvhAabbMin) * m_bvhQuantization;
///Make sure rounding is done in a way that unQuantize(quantizeWithClamp(...)) is conservative
///end-points always set the first bit, so that they are sorted properly (so that neighbouring AABBs overlap properly)
- ///todo: double-check this
+ ///@todo: double-check this
if (isMax)
{
out[0] = (unsigned short) (((unsigned short)(v.getX()+btScalar(1.)) | 1));
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
index a57952ffa06..caed63db005 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
@@ -55,6 +55,7 @@ btSimpleBroadphase::btSimpleBroadphase(int maxProxies, btOverlappingPairCache* o
m_maxHandles = maxProxies;
m_numHandles = 0;
m_firstFreeHandle = 0;
+ m_LastHandleIndex = -1;
{
@@ -88,7 +89,7 @@ btBroadphaseProxy* btSimpleBroadphase::createProxy( const btVector3& aabbMin,
btAssert(0);
return 0; //should never happen, but don't let the game crash ;-)
}
- assert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]);
+ btAssert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]);
int newHandleIndex = allocHandle();
btSimpleBroadphaseProxy* proxy = new (&m_pHandles[newHandleIndex])btSimpleBroadphaseProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy);
@@ -137,14 +138,32 @@ void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg,btDispatcher*
}
+void btSimpleBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+ const btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);
+ aabbMin = sbp->m_aabbMin;
+ aabbMax = sbp->m_aabbMax;
+}
+
void btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* /*dispatcher*/)
{
btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);
- sbp->m_min = aabbMin;
- sbp->m_max = aabbMax;
+ sbp->m_aabbMin = aabbMin;
+ sbp->m_aabbMax = aabbMax;
}
-
+void btSimpleBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin,const btVector3& aabbMax)
+{
+ for (int i=0; i <= m_LastHandleIndex; i++)
+ {
+ btSimpleBroadphaseProxy* proxy = &m_pHandles[i];
+ if(!proxy->m_clientObject)
+ {
+ continue;
+ }
+ rayCallback.process(proxy);
+ }
+}
@@ -154,9 +173,9 @@ void btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbM
bool btSimpleBroadphase::aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1)
{
- return proxy0->m_min[0] <= proxy1->m_max[0] && proxy1->m_min[0] <= proxy0->m_max[0] &&
- proxy0->m_min[1] <= proxy1->m_max[1] && proxy1->m_min[1] <= proxy0->m_max[1] &&
- proxy0->m_min[2] <= proxy1->m_max[2] && proxy1->m_min[2] <= proxy0->m_max[2];
+ return proxy0->m_aabbMin[0] <= proxy1->m_aabbMax[0] && proxy1->m_aabbMin[0] <= proxy0->m_aabbMax[0] &&
+ proxy0->m_aabbMin[1] <= proxy1->m_aabbMax[1] && proxy1->m_aabbMin[1] <= proxy0->m_aabbMax[1] &&
+ proxy0->m_aabbMin[2] <= proxy1->m_aabbMax[2] && proxy1->m_aabbMin[2] <= proxy0->m_aabbMax[2];
}
@@ -176,18 +195,25 @@ void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
{
//first check for new overlapping pairs
int i,j;
-
if (m_numHandles >= 0)
{
-
- for (i=0;i<m_numHandles;i++)
+ int new_largest_index = -1;
+ for (i=0; i <= m_LastHandleIndex; i++)
{
btSimpleBroadphaseProxy* proxy0 = &m_pHandles[i];
-
- for (j=i+1;j<m_numHandles;j++)
+ if(!proxy0->m_clientObject)
+ {
+ continue;
+ }
+ new_largest_index = i;
+ for (j=i+1; j <= m_LastHandleIndex; j++)
{
btSimpleBroadphaseProxy* proxy1 = &m_pHandles[j];
btAssert(proxy0 != proxy1);
+ if(!proxy1->m_clientObject)
+ {
+ continue;
+ }
btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0);
btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1);
@@ -211,6 +237,8 @@ void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
}
}
+ m_LastHandleIndex = new_largest_index;
+
if (m_ownsPairCache && m_pairCache->hasDeferredRemoval())
{
@@ -296,5 +324,7 @@ bool btSimpleBroadphase::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseP
return aabbOverlap(p0,p1);
}
-
-
+void btSimpleBroadphase::resetPool(btDispatcher* dispatcher)
+{
+ //not yet
+}
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
index e2ebb825725..cc7613bf6a0 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
@@ -22,8 +22,6 @@ subject to the following restrictions:
struct btSimpleBroadphaseProxy : public btBroadphaseProxy
{
- btVector3 m_min;
- btVector3 m_max;
int m_nextFree;
// int m_handleId;
@@ -31,9 +29,8 @@ struct btSimpleBroadphaseProxy : public btBroadphaseProxy
btSimpleBroadphaseProxy() {};
- btSimpleBroadphaseProxy(const btPoint3& minpt,const btPoint3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,void* multiSapProxy)
- :btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy),
- m_min(minpt),m_max(maxpt)
+ btSimpleBroadphaseProxy(const btVector3& minpt,const btVector3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,void* multiSapProxy)
+ :btBroadphaseProxy(minpt,maxpt,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy)
{
(void)shapeType;
}
@@ -56,6 +53,7 @@ protected:
int m_numHandles; // number of active handles
int m_maxHandles; // max number of handles
+ int m_LastHandleIndex;
btSimpleBroadphaseProxy* m_pHandles; // handles pool
@@ -68,6 +66,10 @@ protected:
int freeHandle = m_firstFreeHandle;
m_firstFreeHandle = m_pHandles[freeHandle].GetNextFree();
m_numHandles++;
+ if(freeHandle > m_LastHandleIndex)
+ {
+ m_LastHandleIndex = freeHandle;
+ }
return freeHandle;
}
@@ -75,10 +77,15 @@ protected:
{
int handle = int(proxy-m_pHandles);
btAssert(handle >= 0 && handle < m_maxHandles);
-
+ if(handle == m_LastHandleIndex)
+ {
+ m_LastHandleIndex--;
+ }
proxy->SetNextFree(m_firstFreeHandle);
m_firstFreeHandle = handle;
+ proxy->m_clientObject = 0;
+
m_numHandles--;
}
@@ -95,6 +102,15 @@ protected:
return proxy0;
}
+ inline const btSimpleBroadphaseProxy* getSimpleProxyFromProxy(btBroadphaseProxy* proxy) const
+ {
+ const btSimpleBroadphaseProxy* proxy0 = static_cast<const btSimpleBroadphaseProxy*>(proxy);
+ return proxy0;
+ }
+
+ ///reset broadphase internal structures, to ensure determinism/reproducability
+ virtual void resetPool(btDispatcher* dispatcher);
+
void validate();
@@ -117,6 +133,9 @@ public:
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher);
+ virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
+
+ virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0));
btOverlappingPairCache* getOverlappingPairCache()
{
diff --git a/extern/bullet2/src/BulletCollision/CMakeLists.txt b/extern/bullet2/src/BulletCollision/CMakeLists.txt
index d77ca6444c7..4b4304f43b0 100644
--- a/extern/bullet2/src/BulletCollision/CMakeLists.txt
+++ b/extern/bullet2/src/BulletCollision/CMakeLists.txt
@@ -1,153 +1,234 @@
-
-INCLUDE_DIRECTORIES(
-${BULLET_PHYSICS_SOURCE_DIR}/src }
+INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/src } )
+
+SET(BulletCollision_SRCS
+ BroadphaseCollision/btAxisSweep3.cpp
+ BroadphaseCollision/btBroadphaseProxy.cpp
+ BroadphaseCollision/btCollisionAlgorithm.cpp
+ BroadphaseCollision/btDispatcher.cpp
+ BroadphaseCollision/btDbvtBroadphase.cpp
+ BroadphaseCollision/btDbvt.cpp
+ BroadphaseCollision/btMultiSapBroadphase.cpp
+ BroadphaseCollision/btOverlappingPairCache.cpp
+ BroadphaseCollision/btQuantizedBvh.cpp
+ BroadphaseCollision/btSimpleBroadphase.cpp
+ CollisionDispatch/btActivatingCollisionAlgorithm.cpp
+ CollisionDispatch/btCollisionDispatcher.cpp
+ CollisionDispatch/btCollisionObject.cpp
+ CollisionDispatch/btCollisionWorld.cpp
+ CollisionDispatch/btCompoundCollisionAlgorithm.cpp
+ CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
+ CollisionDispatch/btDefaultCollisionConfiguration.cpp
+ CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
+ CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
+ CollisionDispatch/btBoxBoxDetector.cpp
+ CollisionDispatch/btGhostObject.cpp
+ CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
+ CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
+ CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
+ CollisionDispatch/btConvexConvexAlgorithm.cpp
+ CollisionDispatch/btEmptyCollisionAlgorithm.cpp
+ CollisionDispatch/btManifoldResult.cpp
+ CollisionDispatch/btSimulationIslandManager.cpp
+ CollisionDispatch/btUnionFind.cpp
+ CollisionDispatch/SphereTriangleDetector.cpp
+ CollisionShapes/btBoxShape.cpp
+ CollisionShapes/btBvhTriangleMeshShape.cpp
+ CollisionShapes/btCapsuleShape.cpp
+ CollisionShapes/btCollisionShape.cpp
+ CollisionShapes/btCompoundShape.cpp
+ CollisionShapes/btConcaveShape.cpp
+ CollisionShapes/btConeShape.cpp
+ CollisionShapes/btConvexHullShape.cpp
+ CollisionShapes/btConvexPointCloudShape.cpp
+ CollisionShapes/btConvexShape.cpp
+ CollisionShapes/btConvexInternalShape.cpp
+ CollisionShapes/btConvexTriangleMeshShape.cpp
+ CollisionShapes/btCylinderShape.cpp
+ CollisionShapes/btEmptyShape.cpp
+ CollisionShapes/btHeightfieldTerrainShape.cpp
+ CollisionShapes/btMinkowskiSumShape.cpp
+ CollisionShapes/btMultimaterialTriangleMeshShape.cpp
+ CollisionShapes/btMultiSphereShape.cpp
+ CollisionShapes/btOptimizedBvh.cpp
+ CollisionShapes/btPolyhedralConvexShape.cpp
+ CollisionShapes/btScaledBvhTriangleMeshShape.cpp
+ CollisionShapes/btTetrahedronShape.cpp
+ CollisionShapes/btSphereShape.cpp
+ CollisionShapes/btShapeHull.cpp
+ CollisionShapes/btStaticPlaneShape.cpp
+ CollisionShapes/btStridingMeshInterface.cpp
+ CollisionShapes/btTriangleCallback.cpp
+ CollisionShapes/btTriangleBuffer.cpp
+ CollisionShapes/btTriangleIndexVertexArray.cpp
+ CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
+ CollisionShapes/btTriangleMesh.cpp
+ CollisionShapes/btTriangleMeshShape.cpp
+ CollisionShapes/btUniformScalingShape.cpp
+ Gimpact/btContactProcessing.cpp
+ Gimpact/btGImpactShape.cpp
+ Gimpact/gim_contact.cpp
+ Gimpact/btGImpactBvh.cpp
+ Gimpact/btGenericPoolAllocator.cpp
+ Gimpact/gim_memory.cpp
+ Gimpact/btGImpactCollisionAlgorithm.cpp
+ Gimpact/btTriangleShapeEx.cpp
+ Gimpact/gim_tri_collision.cpp
+ Gimpact/btGImpactQuantizedBvh.cpp
+ Gimpact/gim_box_set.cpp
+ NarrowPhaseCollision/btContinuousConvexCollision.cpp
+ NarrowPhaseCollision/btGjkEpa2.cpp
+ NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
+ NarrowPhaseCollision/btConvexCast.cpp
+ NarrowPhaseCollision/btGjkConvexCast.cpp
+ NarrowPhaseCollision/btGjkPairDetector.cpp
+ NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
+ NarrowPhaseCollision/btPersistentManifold.cpp
+ NarrowPhaseCollision/btRaycastCallback.cpp
+ NarrowPhaseCollision/btSubSimplexConvexCast.cpp
+ NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
)
-
-ADD_LIBRARY(LibBulletCollision
- BroadphaseCollision/btAxisSweep3.cpp
- BroadphaseCollision/btAxisSweep3.h
- BroadphaseCollision/btBroadphaseProxy.cpp
- BroadphaseCollision/btBroadphaseProxy.h
- BroadphaseCollision/btCollisionAlgorithm.cpp
- BroadphaseCollision/btCollisionAlgorithm.h
- BroadphaseCollision/btDispatcher.cpp
- BroadphaseCollision/btDispatcher.h
- BroadphaseCollision/btDbvtBroadphase.cpp
- BroadphaseCollision/btDbvtBroadphase.h
- BroadphaseCollision/btDbvt.cpp
- BroadphaseCollision/btDbvt.h
- BroadphaseCollision/btMultiSapBroadphase.cpp
- BroadphaseCollision/btMultiSapBroadphase.h
- BroadphaseCollision/btOverlappingPairCache.cpp
- BroadphaseCollision/btOverlappingPairCache.h
- BroadphaseCollision/btOverlappingPairCallback.h
- BroadphaseCollision/btQuantizedBvh.cpp
- BroadphaseCollision/btQuantizedBvh.h
- BroadphaseCollision/btSimpleBroadphase.cpp
- BroadphaseCollision/btSimpleBroadphase.h
- CollisionDispatch/btCollisionDispatcher.cpp
- CollisionDispatch/btCollisionDispatcher.h
- CollisionDispatch/btCollisionObject.cpp
- CollisionDispatch/btCollisionObject.h
- CollisionDispatch/btCollisionWorld.cpp
- CollisionDispatch/btCollisionWorld.h
- CollisionDispatch/btCompoundCollisionAlgorithm.cpp
- CollisionDispatch/btCompoundCollisionAlgorithm.h
- CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
- CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
- CollisionDispatch/btDefaultCollisionConfiguration.cpp
- CollisionDispatch/btDefaultCollisionConfiguration.h
- CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
- CollisionDispatch/btSphereSphereCollisionAlgorithm.h
- CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
- CollisionDispatch/btBoxBoxCollisionAlgorithm.h
- CollisionDispatch/btBoxBoxDetector.cpp
- CollisionDispatch/btBoxBoxDetector.h
- CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
- CollisionDispatch/btSphereBoxCollisionAlgorithm.h
- CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
- CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
- CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
- CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
- CollisionDispatch/btConvexConvexAlgorithm.cpp
- CollisionDispatch/btConvexConvexAlgorithm.h
- CollisionDispatch/btEmptyCollisionAlgorithm.cpp
- CollisionDispatch/btEmptyCollisionAlgorithm.h
- CollisionDispatch/btManifoldResult.cpp
- CollisionDispatch/btManifoldResult.h
- CollisionDispatch/btSimulationIslandManager.cpp
- CollisionDispatch/btSimulationIslandManager.h
- CollisionDispatch/btUnionFind.cpp
- CollisionDispatch/btUnionFind.h
- CollisionDispatch/SphereTriangleDetector.cpp
- CollisionDispatch/SphereTriangleDetector.h
- CollisionShapes/btBoxShape.cpp
- CollisionShapes/btBoxShape.h
- CollisionShapes/btBvhTriangleMeshShape.cpp
- CollisionShapes/btBvhTriangleMeshShape.h
- CollisionShapes/btCapsuleShape.cpp
- CollisionShapes/btCapsuleShape.h
- CollisionShapes/btCollisionShape.cpp
- CollisionShapes/btCollisionShape.h
- CollisionShapes/btCompoundShape.cpp
- CollisionShapes/btCompoundShape.h
- CollisionShapes/btConcaveShape.cpp
- CollisionShapes/btConcaveShape.h
- CollisionShapes/btConeShape.cpp
- CollisionShapes/btConeShape.h
- CollisionShapes/btConvexHullShape.cpp
- CollisionShapes/btConvexHullShape.h
- CollisionShapes/btConvexShape.cpp
- CollisionShapes/btConvexShape.h
- CollisionShapes/btConvexInternalShape.cpp
- CollisionShapes/btConvexInternalShape.h
- CollisionShapes/btConvexTriangleMeshShape.cpp
- CollisionShapes/btConvexTriangleMeshShape.h
- CollisionShapes/btCylinderShape.cpp
- CollisionShapes/btCylinderShape.h
- CollisionShapes/btEmptyShape.cpp
- CollisionShapes/btEmptyShape.h
- CollisionShapes/btHeightfieldTerrainShape.cpp
- CollisionShapes/btHeightfieldTerrainShape.h
- CollisionShapes/btMinkowskiSumShape.cpp
- CollisionShapes/btMinkowskiSumShape.h
- CollisionShapes/btMaterial.h
- CollisionShapes/btMultimaterialTriangleMeshShape.cpp
- CollisionShapes/btMultimaterialTriangleMeshShape.h
- CollisionShapes/btMultiSphereShape.cpp
- CollisionShapes/btMultiSphereShape.h
- CollisionShapes/btOptimizedBvh.cpp
- CollisionShapes/btOptimizedBvh.h
- CollisionShapes/btPolyhedralConvexShape.cpp
- CollisionShapes/btPolyhedralConvexShape.h
- CollisionShapes/btScaledBvhTriangleMeshShape.cpp
- CollisionShapes/btScaledBvhTriangleMeshShape.h
- CollisionShapes/btTetrahedronShape.cpp
- CollisionShapes/btTetrahedronShape.h
- CollisionShapes/btSphereShape.cpp
- CollisionShapes/btSphereShape.h
- CollisionShapes/btShapeHull.h
- CollisionShapes/btShapeHull.cpp
- CollisionShapes/btStaticPlaneShape.cpp
- CollisionShapes/btStaticPlaneShape.h
- CollisionShapes/btStridingMeshInterface.cpp
- CollisionShapes/btStridingMeshInterface.h
- CollisionShapes/btTriangleCallback.cpp
- CollisionShapes/btTriangleCallback.h
- CollisionShapes/btTriangleBuffer.cpp
- CollisionShapes/btTriangleBuffer.h
- CollisionShapes/btTriangleIndexVertexArray.cpp
- CollisionShapes/btTriangleIndexVertexArray.h
- CollisionShapes/btTriangleIndexVertexMaterialArray.h
- CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
- CollisionShapes/btTriangleMesh.cpp
- CollisionShapes/btTriangleMesh.h
- CollisionShapes/btTriangleMeshShape.cpp
- CollisionShapes/btTriangleMeshShape.h
- CollisionShapes/btUniformScalingShape.cpp
- CollisionShapes/btUniformScalingShape.h
- NarrowPhaseCollision/btContinuousConvexCollision.cpp
- NarrowPhaseCollision/btContinuousConvexCollision.h
- NarrowPhaseCollision/btGjkEpa.cpp
- NarrowPhaseCollision/btGjkEpa.h
- NarrowPhaseCollision/btGjkEpa2.cpp
- NarrowPhaseCollision/btGjkEpa2.h
- NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
- NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
- NarrowPhaseCollision/btConvexCast.cpp
- NarrowPhaseCollision/btConvexCast.h
- NarrowPhaseCollision/btGjkConvexCast.cpp
- NarrowPhaseCollision/btGjkConvexCast.h
- NarrowPhaseCollision/btGjkPairDetector.cpp
- NarrowPhaseCollision/btGjkPairDetector.h
- NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
- NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
- NarrowPhaseCollision/btPersistentManifold.cpp
- NarrowPhaseCollision/btPersistentManifold.h
- NarrowPhaseCollision/btRaycastCallback.cpp
- NarrowPhaseCollision/btRaycastCallback.h
- NarrowPhaseCollision/btSubSimplexConvexCast.cpp
- NarrowPhaseCollision/btSubSimplexConvexCast.h
- NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
- NarrowPhaseCollision/btVoronoiSimplexSolver.h
+
+SET(Root_HDRS
+ ../btBulletCollisionCommon.h
)
+SET(BroadphaseCollision_HDRS
+ BroadphaseCollision/btAxisSweep3.h
+ BroadphaseCollision/btBroadphaseInterface.h
+ BroadphaseCollision/btBroadphaseProxy.h
+ BroadphaseCollision/btCollisionAlgorithm.h
+ BroadphaseCollision/btDispatcher.h
+ BroadphaseCollision/btDbvtBroadphase.h
+ BroadphaseCollision/btDbvt.h
+ BroadphaseCollision/btMultiSapBroadphase.h
+ BroadphaseCollision/btOverlappingPairCache.h
+ BroadphaseCollision/btOverlappingPairCallback.h
+ BroadphaseCollision/btQuantizedBvh.h
+ BroadphaseCollision/btSimpleBroadphase.h
+)
+SET(CollisionDispatch_HDRS
+ CollisionDispatch/btActivatingCollisionAlgorithm.h
+ CollisionDispatch/btCollisionConfiguration.h
+ CollisionDispatch/btCollisionCreateFunc.h
+ CollisionDispatch/btCollisionDispatcher.h
+ CollisionDispatch/btCollisionObject.h
+ CollisionDispatch/btCollisionWorld.h
+ CollisionDispatch/btCompoundCollisionAlgorithm.h
+ CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
+ CollisionDispatch/btDefaultCollisionConfiguration.h
+ CollisionDispatch/btSphereSphereCollisionAlgorithm.h
+ CollisionDispatch/btBoxBoxCollisionAlgorithm.h
+ CollisionDispatch/btBoxBoxDetector.h
+ CollisionDispatch/btGhostObject.h
+ CollisionDispatch/btSphereBoxCollisionAlgorithm.h
+ CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
+ CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
+ CollisionDispatch/btConvexConvexAlgorithm.h
+ CollisionDispatch/btEmptyCollisionAlgorithm.h
+ CollisionDispatch/btManifoldResult.h
+ CollisionDispatch/btSimulationIslandManager.h
+ CollisionDispatch/btUnionFind.h
+ CollisionDispatch/SphereTriangleDetector.h
+)
+SET(CollisionShapes_HDRS
+ CollisionShapes/btBoxShape.h
+ CollisionShapes/btBvhTriangleMeshShape.h
+ CollisionShapes/btCapsuleShape.h
+ CollisionShapes/btCollisionMargin
+ CollisionShapes/btCollisionShape.h
+ CollisionShapes/btCompoundShape.h
+ CollisionShapes/btConcaveShape.h
+ CollisionShapes/btConeShape.h
+ CollisionShapes/btConvexHullShape.h
+ CollisionShapes/btConvexPointCloudShape.h
+ CollisionShapes/btConvexShape.h
+ CollisionShapes/btConvexInternalShape.h
+ CollisionShapes/btConvexTriangleMeshShape.h
+ CollisionShapes/btCylinderShape.h
+ CollisionShapes/btEmptyShape.h
+ CollisionShapes/btHeightfieldTerrainShape.h
+ CollisionShapes/btMinkowskiSumShape.h
+ CollisionShapes/btMaterial.h
+ CollisionShapes/btMultimaterialTriangleMeshShape.h
+ CollisionShapes/btMultiSphereShape.h
+ CollisionShapes/btOptimizedBvh.h
+ CollisionShapes/btPolyhedralConvexShape.h
+ CollisionShapes/btScaledBvhTriangleMeshShape.h
+ CollisionShapes/btTetrahedronShape.h
+ CollisionShapes/btSphereShape.h
+ CollisionShapes/btShapeHull.h
+ CollisionShapes/btStaticPlaneShape.h
+ CollisionShapes/btStridingMeshInterface.h
+ CollisionShapes/btTriangleCallback.h
+ CollisionShapes/btTriangleBuffer.h
+ CollisionShapes/btTriangleIndexVertexArray.h
+ CollisionShapes/btTriangleIndexVertexMaterialArray.h
+ CollisionShapes/btTriangleMesh.h
+ CollisionShapes/btTriangleMeshShape.h
+ CollisionShapes/btUniformScalingShape.h
+)
+SET(Gimpact_HDRS
+ Gimpact/btGImpactShape.h
+ Gimpact/gim_contact.h
+ Gimpact/btGImpactBvh.h
+ Gimpact/btGenericPoolAllocator.h
+ Gimpact/gim_memory.h
+ Gimpact/btGImpactCollisionAlgorithm.h
+ Gimpact/btTriangleShapeEx.h
+ Gimpact/gim_tri_collision.h
+ Gimpact/btGImpactQuantizedBvh.h
+ Gimpact/gim_box_set.h
+)
+SET(NarrowPhaseCollision_HDRS
+ NarrowPhaseCollision/btContinuousConvexCollision.h
+ NarrowPhaseCollision/btConvexCast.h
+ NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
+ NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
+ NarrowPhaseCollision/btGjkConvexCast.h
+ NarrowPhaseCollision/btGjkEpa2.h
+ NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
+ NarrowPhaseCollision/btGjkPairDetector.h
+ NarrowPhaseCollision/btManifoldPoint.h
+ NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
+ NarrowPhaseCollision/btPersistentManifold.h
+ NarrowPhaseCollision/btPointCollector.h
+ NarrowPhaseCollision/btRaycastCallback.h
+ NarrowPhaseCollision/btSimplexSolverInterface.h
+ NarrowPhaseCollision/btSubSimplexConvexCast.h
+ NarrowPhaseCollision/btVoronoiSimplexSolver.h
+)
+
+SET(BulletCollision_HDRS
+ ${Root_HDRS}
+ ${BroadphaseCollision_HDRS}
+ ${CollisionDispatch_HDRS}
+ ${CollisionShapes_HDRS}
+ ${Gimpact_HDRS}
+ ${NarrowPhaseCollision_HDRS}
+)
+
+
+ADD_LIBRARY(BulletCollision ${BulletCollision_SRCS} ${BulletCollision_HDRS})
+SET_TARGET_PROPERTIES(BulletCollision PROPERTIES VERSION ${BULLET_VERSION})
+SET_TARGET_PROPERTIES(BulletCollision PROPERTIES SOVERSION ${BULLET_VERSION})
+IF (BUILD_SHARED_LIBS)
+ TARGET_LINK_LIBRARIES(BulletCollision LinearMath)
+ENDIF (BUILD_SHARED_LIBS)
+
+#INSTALL of other files requires CMake 2.6
+IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
+ INSTALL(TARGETS BulletCollision DESTINATION lib)
+ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h")
+ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
+
+IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
+ SET_TARGET_PROPERTIES(BulletCollision PROPERTIES FRAMEWORK true)
+
+ SET_TARGET_PROPERTIES(BulletCollision PROPERTIES PUBLIC_HEADER "${Root_HDRS}")
+ # Have to list out sub-directories manually:
+ SET_PROPERTY(SOURCE ${BroadphaseCollision_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/BroadphaseCollision)
+ SET_PROPERTY(SOURCE ${CollisionDispatch_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/CollisionDispatch)
+ SET_PROPERTY(SOURCE ${CollisionShapes_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/CollisionShapes)
+ SET_PROPERTY(SOURCE ${Gimpact_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/Gimpact)
+ SET_PROPERTY(SOURCE ${NarrowPhaseCollision_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/NarrowPhaseCollision)
+
+ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
index f6c1e32ac7c..9a749a03793 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
@@ -19,9 +19,10 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btSphereShape.h"
-SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle)
+SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle,btScalar contactBreakingThreshold)
:m_sphere(sphere),
-m_triangle(triangle)
+m_triangle(triangle),
+m_contactBreakingThreshold(contactBreakingThreshold)
{
}
@@ -40,7 +41,7 @@ void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Res
//move sphere into triangle space
btTransform sphereInTr = transformB.inverseTimes(transformA);
- if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact))
+ if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact,m_contactBreakingThreshold))
{
if (swapResults)
{
@@ -93,7 +94,7 @@ bool SphereTriangleDetector::facecontains(const btVector3 &p,const btVector3* ve
}
///combined discrete/continuous sphere-triangle
-bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact)
+bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold)
{
const btVector3* vertices = &m_triangle->getVertexPtr(0);
@@ -115,10 +116,7 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
normal *= btScalar(-1.);
}
- ///todo: move this gContactBreakingThreshold into a proper structure
- extern btScalar gContactBreakingThreshold;
-
- btScalar contactMargin = gContactBreakingThreshold;
+ btScalar contactMargin = contactBreakingThreshold;
bool isInsideContactPlane = distanceFromPlane < r + contactMargin;
bool isInsideShellPlane = distanceFromPlane < r;
@@ -140,8 +138,8 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
btVector3 nearestOnEdge;
for (int i = 0; i < m_triangle->getNumEdges(); i++) {
- btPoint3 pa;
- btPoint3 pb;
+ btVector3 pa;
+ btVector3 pb;
m_triangle->getEdge(i,pa,pb);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
index 26dabaa480e..981bd54e76c 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
@@ -17,7 +17,7 @@ subject to the following restrictions:
#define SPHERE_TRIANGLE_DETECTOR_H
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
-#include "LinearMath/btPoint3.h"
+
class btSphereShape;
@@ -30,19 +30,19 @@ struct SphereTriangleDetector : public btDiscreteCollisionDetectorInterface
{
virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false);
- SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle);
+ SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle, btScalar contactBreakingThreshold);
virtual ~SphereTriangleDetector() {};
private:
- bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact);
+ bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold);
bool pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p );
bool facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal);
btSphereShape* m_sphere;
btTriangleShape* m_triangle;
-
+ btScalar m_contactBreakingThreshold;
};
#endif //SPHERE_TRIANGLE_DETECTOR_H
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp
new file mode 100644
index 00000000000..7e5da6c5872
--- /dev/null
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp
@@ -0,0 +1,47 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.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 "btActivatingCollisionAlgorithm.h"
+#include "btCollisionDispatcher.h"
+#include "btCollisionObject.h"
+
+btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci)
+:btCollisionAlgorithm(ci)
+//,
+//m_colObj0(0),
+//m_colObj1(0)
+{
+}
+btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* colObj0,btCollisionObject* colObj1)
+:btCollisionAlgorithm(ci)
+//,
+//m_colObj0(0),
+//m_colObj1(0)
+{
+// if (ci.m_dispatcher1->needsCollision(colObj0,colObj1))
+// {
+// m_colObj0 = colObj0;
+// m_colObj1 = colObj1;
+//
+// m_colObj0->activate();
+// m_colObj1->activate();
+// }
+}
+
+btActivatingCollisionAlgorithm::~btActivatingCollisionAlgorithm()
+{
+// m_colObj0->activate();
+// m_colObj1->activate();
+}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h
new file mode 100644
index 00000000000..25fe088942d
--- /dev/null
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h
@@ -0,0 +1,36 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.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_ACTIVATING_COLLISION_ALGORITHM_H
+#define __BT_ACTIVATING_COLLISION_ALGORITHM_H
+
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+
+///This class is not enabled yet (work-in-progress) to more aggressively activate objects.
+class btActivatingCollisionAlgorithm : public btCollisionAlgorithm
+{
+// btCollisionObject* m_colObj0;
+// btCollisionObject* m_colObj1;
+
+public:
+
+ btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci);
+
+ btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* colObj0,btCollisionObject* colObj1);
+
+ virtual ~btActivatingCollisionAlgorithm();
+
+};
+#endif //__BT_ACTIVATING_COLLISION_ALGORITHM_H
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
index cd0c028012c..d3342c547b5 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
@@ -22,7 +22,7 @@ subject to the following restrictions:
#define USE_PERSISTENT_CONTACTS 1
btBoxBoxCollisionAlgorithm::btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* obj0,btCollisionObject* obj1)
-: btCollisionAlgorithm(ci),
+: btActivatingCollisionAlgorithm(ci,obj0,obj1),
m_ownManifold(false),
m_manifoldPtr(mf)
{
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h
index 35afaf175a1..e7d2cc25c22 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef BOX_BOX__COLLISION_ALGORITHM_H
#define BOX_BOX__COLLISION_ALGORITHM_H
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
@@ -24,14 +24,14 @@ subject to the following restrictions:
class btPersistentManifold;
///box-box collision detection
-class btBoxBoxCollisionAlgorithm : public btCollisionAlgorithm
+class btBoxBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm
{
bool m_ownManifold;
btPersistentManifold* m_manifoldPtr;
public:
btBoxBoxCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
- : btCollisionAlgorithm(ci) {}
+ : btActivatingCollisionAlgorithm(ci) {}
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp
index 45ebff5dc45..31353f1b2c4 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp
@@ -207,7 +207,13 @@ void cullPoints2 (int n, btScalar p[], int m, int i0, int iret[])
cy += q*(p[i*2+1]+p[i*2+3]);
}
q = p[n*2-2]*p[1] - p[0]*p[n*2-1];
- a = 1.f/(btScalar(3.0)*(a+q));
+ if (btFabs(a+q) > SIMD_EPSILON)
+ {
+ a = 1.f/(btScalar(3.0)*(a+q));
+ } else
+ {
+ a=1e30f;
+ }
cx = a*(cx + q*(p[n*2-2]+p[0]));
cy = a*(cy + q*(p[n*2-1]+p[1]));
}
@@ -226,9 +232,9 @@ void cullPoints2 (int n, btScalar p[], int m, int i0, int iret[])
a = btScalar(j)*(2*M__PI/m) + A[i0];
if (a > M__PI) a -= 2*M__PI;
btScalar maxdiff=1e9,diff;
-#if defined(DEBUG) || defined (_DEBUG)
- *iret = i0; // iret is not allowed to keep this value
-#endif
+
+ *iret = i0; // iret is not allowed to keep this value, but it sometimes does, when diff=#QNAN0
+
for (i=0; i<n; i++) {
if (avail[i]) {
diff = btFabs (A[i]-a);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h
index fad770ac26d..1db51a36d03 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h
@@ -22,7 +22,7 @@ class btPoolAllocator;
///btCollisionConfiguration allows to configure Bullet collision detection
///stack allocator size, default collision algorithms and persistent manifold pool size
-///todo: describe the meaning
+///@todo: describe the meaning
class btCollisionConfiguration
{
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h
index c6728918d16..a6da5f61a3c 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h
@@ -17,7 +17,6 @@ subject to the following restrictions:
#define COLLISION_CREATE_FUNC
#include "LinearMath/btAlignedObjectArray.h"
-typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
class btCollisionAlgorithm;
class btCollisionObject;
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
index a031a9f9784..e6ff2130aad 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
@@ -52,12 +52,12 @@ btCollisionDispatcher::btCollisionDispatcher (btCollisionConfiguration* collisio
for (int j=0;j<MAX_BROADPHASE_COLLISION_TYPES;j++)
{
m_doubleDispatch[i][j] = m_collisionConfiguration->getCollisionAlgorithmCreateFunc(i,j);
- assert(m_doubleDispatch[i][j]);
+ btAssert(m_doubleDispatch[i][j]);
}
}
-};
+}
void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc)
@@ -78,7 +78,13 @@ btPersistentManifold* btCollisionDispatcher::getNewManifold(void* b0,void* b1)
btCollisionObject* body0 = (btCollisionObject*)b0;
btCollisionObject* body1 = (btCollisionObject*)b1;
-
+
+ //test for Bullet 2.74: use a relative contact breaking threshold without clamping against 'gContactBreakingThreshold'
+ //btScalar contactBreakingThreshold = btMin(gContactBreakingThreshold,btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold()));
+ btScalar contactBreakingThreshold = btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold());
+
+ btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(),body1->getContactProcessingThreshold());
+
void* mem = 0;
if (m_persistentManifoldPoolAllocator->getFreeCount())
@@ -89,7 +95,7 @@ btPersistentManifold* btCollisionDispatcher::getNewManifold(void* b0,void* b1)
mem = btAlignedAlloc(sizeof(btPersistentManifold),16);
}
- btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0);
+ btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0,contactBreakingThreshold,contactProcessingThreshold);
manifold->m_index1a = m_manifoldsPtr.size();
m_manifoldsPtr.push_back(manifold);
@@ -144,7 +150,6 @@ btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* bo
-
bool btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionObject* body1)
{
//here you can do filtering
@@ -158,8 +163,8 @@ bool btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionOb
bool btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionObject* body1)
{
- assert(body0);
- assert(body1);
+ btAssert(body0);
+ btAssert(body1);
bool needsCollision = true;
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp
index 846c9b9b989..285b8f174e4 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp
@@ -19,6 +19,7 @@ subject to the following restrictions:
btCollisionObject::btCollisionObject()
: m_anisotropicFriction(1.f,1.f,1.f),
m_hasAnisotropicFriction(false),
+ m_contactProcessingThreshold(0.f),
m_broadphaseHandle(0),
m_collisionShape(0),
m_rootCollisionShape(0),
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h
index 8442868cf89..0d5b7886443 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h
@@ -29,8 +29,11 @@ struct btBroadphaseProxy;
class btCollisionShape;
#include "LinearMath/btMotionState.h"
#include "LinearMath/btAlignedAllocator.h"
+#include "LinearMath/btAlignedObjectArray.h"
+typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
+
/// btCollisionObject can be used to manage collision detection objects.
/// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy.
@@ -49,8 +52,10 @@ protected:
//without destroying the continuous interpolated motion (which uses this interpolation velocities)
btVector3 m_interpolationLinearVelocity;
btVector3 m_interpolationAngularVelocity;
+
btVector3 m_anisotropicFriction;
- bool m_hasAnisotropicFriction;
+ bool m_hasAnisotropicFriction;
+ btScalar m_contactProcessingThreshold;
btBroadphaseProxy* m_broadphaseHandle;
btCollisionShape* m_collisionShape;
@@ -74,7 +79,7 @@ protected:
///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
void* m_userObjectPointer;
- ///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody etc.
+ ///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc.
///do not assign your own m_internalType unless you write a new dynamics object class.
int m_internalType;
@@ -106,14 +111,19 @@ public:
CF_STATIC_OBJECT= 1,
CF_KINEMATIC_OBJECT= 2,
CF_NO_CONTACT_RESPONSE = 4,
- CF_CUSTOM_MATERIAL_CALLBACK = 8//this allows per-triangle material (friction/restitution)
+ CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution)
+ CF_CHARACTER_OBJECT = 16
};
enum CollisionObjectTypes
{
CO_COLLISION_OBJECT =1,
CO_RIGID_BODY,
- CO_SOFT_BODY
+ ///CO_GHOST_OBJECT keeps track of all objects overlapping its AABB and that pass its collision filter
+ ///It is useful for collision sensors, explosion objects, character controller etc.
+ CO_GHOST_OBJECT,
+ CO_SOFT_BODY,
+ CO_HF_FLUID
};
SIMD_FORCE_INLINE bool mergesSimulationIslands() const
@@ -136,6 +146,16 @@ public:
return m_hasAnisotropicFriction;
}
+ ///the constraint solver can discard solving contacts, if the distance is above this threshold. 0 by default.
+ ///Note that using contacts with positive distance can improve stability. It increases, however, the chance of colliding with degerate contacts, such as 'interior' triangle edges
+ void setContactProcessingThreshold( btScalar contactProcessingThreshold)
+ {
+ m_contactProcessingThreshold = contactProcessingThreshold;
+ }
+ btScalar getContactProcessingThreshold() const
+ {
+ return m_contactProcessingThreshold;
+ }
SIMD_FORCE_INLINE bool isStaticObject() const {
return (m_collisionFlags & CF_STATIC_OBJECT) != 0;
@@ -193,7 +213,7 @@ public:
m_collisionShape = collisionShape;
}
- int getActivationState() const { return m_activationState1;}
+ SIMD_FORCE_INLINE int getActivationState() const { return m_activationState1;}
void setActivationState(int newState);
@@ -210,7 +230,7 @@ public:
void activate(bool forceActivation = false);
- inline bool isActive() const
+ SIMD_FORCE_INLINE bool isActive() const
{
return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION));
}
@@ -254,12 +274,12 @@ public:
}
- btBroadphaseProxy* getBroadphaseHandle()
+ SIMD_FORCE_INLINE btBroadphaseProxy* getBroadphaseHandle()
{
return m_broadphaseHandle;
}
- const btBroadphaseProxy* getBroadphaseHandle() const
+ SIMD_FORCE_INLINE const btBroadphaseProxy* getBroadphaseHandle() const
{
return m_broadphaseHandle;
}
@@ -305,7 +325,7 @@ public:
return m_interpolationAngularVelocity;
}
- const int getIslandTag() const
+ SIMD_FORCE_INLINE int getIslandTag() const
{
return m_islandTag1;
}
@@ -315,7 +335,7 @@ public:
m_islandTag1 = tag;
}
- const int getCompanionId() const
+ SIMD_FORCE_INLINE int getCompanionId() const
{
return m_companionId;
}
@@ -325,7 +345,7 @@ public:
m_companionId = id;
}
- const btScalar getHitFraction() const
+ SIMD_FORCE_INLINE btScalar getHitFraction() const
{
return m_hitFraction;
}
@@ -336,7 +356,7 @@ public:
}
- const int getCollisionFlags() const
+ SIMD_FORCE_INLINE int getCollisionFlags() const
{
return m_collisionFlags;
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
index d8674a320a7..10e880e2523 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
@@ -32,6 +32,9 @@ subject to the following restrictions:
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btStackAlloc.h"
+//#define USE_BRUTEFORCE_RAYBROADPHASE 1
+//RECALCULATE_AABB is slower, but benefit is that you don't need to call 'stepSimulation' or 'updateAabbs' before using a rayTest
+//#define RECALCULATE_AABB_RAYCAST 1
//When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor)
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
@@ -66,6 +69,7 @@ btCollisionWorld::~btCollisionWorld()
//
getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
getBroadphase()->destroyProxy(bp,m_dispatcher1);
+ collisionObject->setBroadphaseHandle(0);
}
}
@@ -113,6 +117,41 @@ void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,sho
}
+
+
+void btCollisionWorld::updateSingleAabb(btCollisionObject* colObj)
+{
+ btVector3 minAabb,maxAabb;
+ colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
+ //need to increase the aabb for contact thresholds
+ btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);
+ minAabb -= contactThreshold;
+ maxAabb += contactThreshold;
+
+ btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache;
+
+ //moving objects should be moderately sized, probably something wrong if not
+ if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12)))
+ {
+ bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
+ } else
+ {
+ //something went wrong, investigate
+ //this assert is unwanted in 3D modelers (danger of loosing work)
+ colObj->setActivationState(DISABLE_SIMULATION);
+
+ static bool reportMe = true;
+ if (reportMe && m_debugDrawer)
+ {
+ reportMe = false;
+ m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation");
+ m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n");
+ m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n");
+ m_debugDrawer->reportErrorWarning("Thanks.\n");
+ }
+ }
+}
+
void btCollisionWorld::updateAabbs()
{
BT_PROFILE("updateAabbs");
@@ -125,38 +164,9 @@ void btCollisionWorld::updateAabbs()
//only update aabb of active objects
if (colObj->isActive())
{
- btPoint3 minAabb,maxAabb;
- colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
- //need to increase the aabb for contact thresholds
- btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);
- minAabb -= contactThreshold;
- maxAabb += contactThreshold;
-
- btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache;
-
- //moving objects should be moderately sized, probably something wrong if not
- if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12)))
- {
- bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
- } else
- {
- //something went wrong, investigate
- //this assert is unwanted in 3D modelers (danger of loosing work)
- colObj->setActivationState(DISABLE_SIMULATION);
-
- static bool reportMe = true;
- if (reportMe && m_debugDrawer)
- {
- reportMe = false;
- m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation");
- m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n");
- m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n");
- m_debugDrawer->reportErrorWarning("Thanks.\n");
- }
- }
+ updateSingleAabb(colObj);
}
}
-
}
@@ -226,6 +236,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
if (collisionShape->isConvex())
{
+// BT_PROFILE("rayTestConvex");
btConvexCast::CastResult castResult;
castResult.m_fraction = resultCallback.m_closestHitFraction;
@@ -269,6 +280,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
} else {
if (collisionShape->isConcave())
{
+// BT_PROFILE("rayTestConcave");
if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
{
///optimized version for btBvhTriangleMeshShape
@@ -286,7 +298,8 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh):
- btTriangleRaycastCallback(from,to),
+ //@BP Mod
+ btTriangleRaycastCallback(from,to, resultCallback->m_flags),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
m_triangleMesh(triangleMesh)
@@ -317,7 +330,8 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
} else
{
- btTriangleMeshShape* triangleMesh = (btTriangleMeshShape*)collisionShape;
+ //generic (slower) case
+ btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
@@ -330,11 +344,12 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
{
btCollisionWorld::RayResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
- btTriangleMeshShape* m_triangleMesh;
+ btConcaveShape* m_triangleMesh;
BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
- btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh):
- btTriangleRaycastCallback(from,to),
+ btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh):
+ //@BP Mod
+ btTriangleRaycastCallback(from,to, resultCallback->m_flags),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
m_triangleMesh(triangleMesh)
@@ -363,7 +378,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
};
- BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
+ BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,concaveShape);
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
btVector3 rayAabbMinLocal = rayFromLocal;
@@ -371,10 +386,11 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
btVector3 rayAabbMaxLocal = rayFromLocal;
rayAabbMaxLocal.setMax(rayToLocal);
- triangleMesh->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
+ concaveShape->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
}
} else {
- //todo: use AABB tree or other BVH acceleration structure!
+// BT_PROFILE("rayTestCompound");
+ ///@todo: use AABB tree or other BVH acceleration structure, see btDbvt
if (collisionShape->isCompound())
{
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
@@ -408,9 +424,10 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
{
if (collisionShape->isConvex())
{
+ //BT_PROFILE("convexSweepConvex");
btConvexCast::CastResult castResult;
castResult.m_allowedPenetration = allowedPenetration;
- castResult.m_fraction = btScalar(1.);//??
+ castResult.m_fraction = resultCallback.m_closestHitFraction;//btScalar(1.);//??
btConvexShape* convexShape = (btConvexShape*) collisionShape;
btVoronoiSimplexSolver simplexSolver;
@@ -452,6 +469,7 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
{
if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
{
+ //BT_PROFILE("convexSweepbtBvhTriangleMesh");
btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
@@ -508,7 +526,8 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal);
} else
{
- btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
+ //BT_PROFILE("convexSweepConcave");
+ btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
btTransform worldTocollisionObject = colObjWorldTransform.inverse();
btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
@@ -520,10 +539,10 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
{
btCollisionWorld::ConvexResultCallback* m_resultCallback;
btCollisionObject* m_collisionObject;
- btTriangleMeshShape* m_triangleMesh;
+ btConcaveShape* m_triangleMesh;
BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
- btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):
+ btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& triangleToWorld):
btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
@@ -556,7 +575,7 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
};
- BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
+ BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
tccb.m_hitFraction = resultCallback.m_closestHitFraction;
btVector3 boxMinLocal, boxMaxLocal;
castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
@@ -567,12 +586,13 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
rayAabbMaxLocal.setMax(convexToLocal);
rayAabbMinLocal += boxMinLocal;
rayAabbMaxLocal += boxMaxLocal;
- triangleMesh->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
+ concaveShape->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
}
} else {
- //todo: use AABB tree or other BVH acceleration structure!
+ ///@todo : use AABB tree or other BVH acceleration structure!
if (collisionShape->isCompound())
{
+ BT_PROFILE("convexSweepCompound");
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
int i=0;
for (i=0;i<compoundShape->getNumChildShapes();i++)
@@ -596,51 +616,173 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
}
}
-void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
+
+struct btSingleRayCallback : public btBroadphaseRayCallback
{
+ btVector3 m_rayFromWorld;
+ btVector3 m_rayToWorld;
+ btTransform m_rayFromTrans;
+ btTransform m_rayToTrans;
+ btVector3 m_hitNormal;
- btTransform rayFromTrans,rayToTrans;
- rayFromTrans.setIdentity();
- rayFromTrans.setOrigin(rayFromWorld);
- rayToTrans.setIdentity();
+ const btCollisionWorld* m_world;
+ btCollisionWorld::RayResultCallback& m_resultCallback;
- rayToTrans.setOrigin(rayToWorld);
+ btSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btCollisionWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
+ :m_rayFromWorld(rayFromWorld),
+ m_rayToWorld(rayToWorld),
+ m_world(world),
+ m_resultCallback(resultCallback)
+ {
+ m_rayFromTrans.setIdentity();
+ m_rayFromTrans.setOrigin(m_rayFromWorld);
+ m_rayToTrans.setIdentity();
+ m_rayToTrans.setOrigin(m_rayToWorld);
- /// go over all objects, and if the ray intersects their aabb, do a ray-shape query using convexCaster (CCD)
+ btVector3 rayDir = (rayToWorld-rayFromWorld);
- int i;
- for (i=0;i<m_collisionObjects.size();i++)
+ rayDir.normalize ();
+ ///what about division by zero? --> just set rayDirection[i] to INF/1e30
+ m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
+ m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
+ m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+ m_signs[0] = m_rayDirectionInverse[0] < 0.0;
+ m_signs[1] = m_rayDirectionInverse[1] < 0.0;
+ m_signs[2] = m_rayDirectionInverse[2] < 0.0;
+
+ m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld);
+
+ }
+
+
+
+ virtual bool process(const btBroadphaseProxy* proxy)
{
///terminate further ray tests, once the closestHitFraction reached zero
- if (resultCallback.m_closestHitFraction == btScalar(0.f))
- break;
+ if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
+ return false;
+
+ btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
- btCollisionObject* collisionObject= m_collisionObjects[i];
//only perform raycast if filterMask matches
- if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
+ if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
+ {
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
+ //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
+#if 0
+#ifdef RECALCULATE_AABB
btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
-
- btScalar hitLambda = resultCallback.m_closestHitFraction;
- btVector3 hitNormal;
- if (btRayAabb(rayFromWorld,rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
+#else
+ //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
+ const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
+ const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
+#endif
+#endif
+ //btScalar hitLambda = m_resultCallback.m_closestHitFraction;
+ //culling already done by broadphase
+ //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
{
- rayTestSingle(rayFromTrans,rayToTrans,
+ m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
collisionObject,
collisionObject->getCollisionShape(),
collisionObject->getWorldTransform(),
- resultCallback);
+ m_resultCallback);
}
}
-
+ return true;
}
+};
+
+void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
+{
+ BT_PROFILE("rayTest");
+ /// use the broadphase to accelerate the search for objects, based on their aabb
+ /// and for each object with ray-aabb overlap, perform an exact ray test
+ btSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
+
+#ifndef USE_BRUTEFORCE_RAYBROADPHASE
+ m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
+#else
+ for (int i=0;i<this->getNumCollisionObjects();i++)
+ {
+ rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
+ }
+#endif //USE_BRUTEFORCE_RAYBROADPHASE
}
-void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback) const
+
+struct btSingleSweepCallback : public btBroadphaseRayCallback
{
+
+ btTransform m_convexFromTrans;
+ btTransform m_convexToTrans;
+ btVector3 m_hitNormal;
+ const btCollisionWorld* m_world;
+ btCollisionWorld::ConvexResultCallback& m_resultCallback;
+ btScalar m_allowedCcdPenetration;
+ const btConvexShape* m_castShape;
+
+
+ btSingleSweepCallback(const btConvexShape* castShape, const btTransform& convexFromTrans,const btTransform& convexToTrans,const btCollisionWorld* world,btCollisionWorld::ConvexResultCallback& resultCallback,btScalar allowedPenetration)
+ :m_convexFromTrans(convexFromTrans),
+ m_convexToTrans(convexToTrans),
+ m_world(world),
+ m_resultCallback(resultCallback),
+ m_allowedCcdPenetration(allowedPenetration),
+ m_castShape(castShape)
+ {
+ btVector3 unnormalizedRayDir = (m_convexToTrans.getOrigin()-m_convexFromTrans.getOrigin());
+ btVector3 rayDir = unnormalizedRayDir.normalized();
+ ///what about division by zero? --> just set rayDirection[i] to INF/1e30
+ m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
+ m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
+ m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+ m_signs[0] = m_rayDirectionInverse[0] < 0.0;
+ m_signs[1] = m_rayDirectionInverse[1] < 0.0;
+ m_signs[2] = m_rayDirectionInverse[2] < 0.0;
+
+ m_lambda_max = rayDir.dot(unnormalizedRayDir);
+
+ }
+
+ virtual bool process(const btBroadphaseProxy* proxy)
+ {
+ ///terminate further convex sweep tests, once the closestHitFraction reached zero
+ if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
+ return false;
+
+ btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
+
+ //only perform raycast if filterMask matches
+ if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
+ //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
+ m_world->objectQuerySingle(m_castShape, m_convexFromTrans,m_convexToTrans,
+ collisionObject,
+ collisionObject->getCollisionShape(),
+ collisionObject->getWorldTransform(),
+ m_resultCallback,
+ m_allowedCcdPenetration);
+ }
+
+ return true;
+ }
+};
+
+
+
+void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
+{
+
+ BT_PROFILE("convexSweepTest");
+ /// use the broadphase to accelerate the search for objects, based on their aabb
+ /// and for each object with ray-aabb overlap, perform an exact ray test
+ /// unfortunately the implementation for rayTest and convexSweepTest duplicated, albeit practically identical
+
+
+
btTransform convexFromTrans,convexToTrans;
convexFromTrans = convexFromWorld;
convexToTrans = convexToWorld;
@@ -649,12 +791,21 @@ void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btT
{
btVector3 linVel, angVel;
btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
+ btVector3 zeroLinVel;
+ zeroLinVel.setValue(0,0,0);
btTransform R;
R.setIdentity ();
R.setRotation (convexFromTrans.getRotation());
- castShape->calculateTemporalAabb (R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
+ castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
}
+#ifndef USE_BRUTEFORCE_RAYBROADPHASE
+
+ btSingleSweepCallback convexCB(castShape,convexFromWorld,convexToWorld,this,resultCallback,allowedCcdPenetration);
+
+ m_broadphasePairCache->rayTest(convexFromTrans.getOrigin(),convexToTrans.getOrigin(),convexCB,castShapeAabbMin,castShapeAabbMax);
+
+#else
/// go over all objects, and if the ray intersects their aabb + cast shape aabb,
// do a ray-shape query using convexCaster (CCD)
int i;
@@ -676,9 +827,9 @@ void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btT
collisionObject->getCollisionShape(),
collisionObject->getWorldTransform(),
resultCallback,
- getDispatchInfo().m_allowedCcdPenetration);
+ allowedCcdPenetration);
}
}
}
-
+#endif //USE_BRUTEFORCE_RAYBROADPHASE
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
index 7557691a9a9..87f7137a55b 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
@@ -1,6 +1,6 @@
/*
Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2006 Erwin Coumans http://bulletphysics.com/Bullet/
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.
@@ -22,39 +22,39 @@ subject to the following restrictions:
*
* Bullet is a Collision Detection and Rigid Body Dynamics Library. The Library is Open Source and free for commercial use, under the ZLib license ( http://opensource.org/licenses/zlib-license.php ).
*
- * There is the Physics Forum for Feedback and bteral Collision Detection and Physics discussions.
- * Please visit http://www.continuousphysics.com/Bullet/phpBB2/index.php
+ * There is the Physics Forum for feedback and general Collision Detection and Physics discussions.
+ * Please visit http://www.bulletphysics.com
*
* @section install_sec Installation
*
* @subsection step1 Step 1: Download
- * You can download the Bullet Physics Library from our website: http://www.continuousphysics.com/Bullet/
+ * You can download the Bullet Physics Library from the Google Code repository: http://code.google.com/p/bullet/downloads/list
* @subsection step2 Step 2: Building
* Bullet comes with autogenerated Project Files for Microsoft Visual Studio 6, 7, 7.1 and 8.
* The main Workspace/Solution is located in Bullet/msvc/8/wksbullet.sln (replace 8 with your version).
*
- * Under other platforms, like Linux or Mac OS-X, Bullet can be build using either using cmake, http://www.cmake.org, or jam, http://www.perforce.com/jam/jam.html . cmake can autogenerate Xcode, KDevelop, MSVC and other build systems. just run cmake . in the root of Bullet.
+ * Under other platforms, like Linux or Mac OS-X, Bullet can be build using either using make, cmake, http://www.cmake.org , or jam, http://www.perforce.com/jam/jam.html . cmake can autogenerate Xcode, KDevelop, MSVC and other build systems. just run cmake . in the root of Bullet.
+ * So if you are not using MSVC or cmake, you can run ./autogen.sh ./configure to create both Makefile and Jamfile and then run make or jam.
* Jam is a build system that can build the library, demos and also autogenerate the MSVC Project Files.
- * So if you are not using MSVC, you can run configure and jam .
- * If you don't have jam installed, you can make jam from the included jam-2.5 sources, or download jam from ftp://ftp.perforce.com/pub/jam/
+ * If you don't have jam installed, you can make jam from the included jam-2.5 sources, or download jam from ftp://ftp.perforce.com/jam
*
* @subsection step3 Step 3: Testing demos
- * Try to run and experiment with CcdPhysicsDemo executable as a starting point.
+ * Try to run and experiment with BasicDemo executable as a starting point.
* Bullet can be used in several ways, as Full Rigid Body simulation, as Collision Detector Library or Low Level / Snippets like the GJK Closest Point calculation.
* The Dependencies can be seen in this documentation under Directories
*
- * @subsection step4 Step 4: Integrating in your application, Full Rigid Body Simulation
- * Check out CcdPhysicsDemo how to create a btDynamicsWorld, btRigidBody and btCollisionShape, Stepping the simulation and synchronizing your graphics object transform.
- * PLEASE NOTE THE CcdPhysicsEnvironment and CcdPhysicsController is obsolete and will be removed. It has been replaced by classes derived frmo btDynamicsWorld and btRididBody
+ * @subsection step4 Step 4: Integrating in your application, full Rigid Body and Soft Body simulation
+ * Check out BasicDemo how to create a btDynamicsWorld, btRigidBody and btCollisionShape, Stepping the simulation and synchronizing your graphics object transform.
+ * Check out SoftDemo how to use soft body dynamics, using btSoftRigidDynamicsWorld.
* @subsection step5 Step 5 : Integrate the Collision Detection Library (without Dynamics and other Extras)
* Bullet Collision Detection can also be used without the Dynamics/Extras.
- * Check out btCollisionWorld and btCollisionObject, and the CollisionInterfaceDemo. Also in Extras/test_BulletOde.cpp there is a sample Collision Detection integration with Open Dynamics Engine, ODE, http://www.ode.org
+ * Check out btCollisionWorld and btCollisionObject, and the CollisionInterfaceDemo.
* @subsection step6 Step 6 : Use Snippets like the GJK Closest Point calculation.
* Bullet has been designed in a modular way keeping dependencies to a minimum. The ConvexHullDistance demo demonstrates direct use of btGjkPairDetector.
*
* @section copyright Copyright
- * Copyright (C) 2005-2007 Erwin Coumans, some contributions Copyright Gino van den Bergen, Christer Ericson, Simon Hobbs, Ricardo Padrela, F Richter(res), Stephane Redon
- * Special thanks to all visitors of the Bullet Physics forum, and in particular above contributors, Dave Eberle, Dirk Gregorius, Erin Catto, Dave Eberle, Adam Moravanszky,
+ * Copyright (C) 2005-2008 Erwin Coumans, some contributions Copyright Gino van den Bergen, Christer Ericson, Simon Hobbs, Ricardo Padrela, F Richter(res), Stephane Redon
+ * Special thanks to all visitors of the Bullet Physics forum, and in particular above contributors, John McCutchan, Nathanael Presson, Dave Eberle, Dirk Gregorius, Erin Catto, Dave Eberle, Adam Moravanszky,
* Pierre Terdiman, Kenny Erleben, Russell Smith, Oliver Strunk, Jan Paul van Waveren, Marten Svanfeldt.
*
*/
@@ -71,7 +71,7 @@ class btBroadphaseInterface;
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "btCollisionObject.h"
-#include "btCollisionDispatcher.h" //for definition of btCollisionObjectArray
+#include "btCollisionDispatcher.h"
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
#include "LinearMath/btAlignedObjectArray.h"
@@ -107,6 +107,11 @@ public:
m_broadphasePairCache = pairCache;
}
+ const btBroadphaseInterface* getBroadphase() const
+ {
+ return m_broadphasePairCache;
+ }
+
btBroadphaseInterface* getBroadphase()
{
return m_broadphasePairCache;
@@ -128,8 +133,10 @@ public:
return m_dispatcher1;
}
- virtual void updateAabbs();
+ void updateSingleAabb(btCollisionObject* colObj);
+ virtual void updateAabbs();
+
virtual void setDebugDrawer(btIDebugDraw* debugDrawer)
{
m_debugDrawer = debugDrawer;
@@ -179,6 +186,8 @@ public:
btCollisionObject* m_collisionObject;
short int m_collisionFilterGroup;
short int m_collisionFilterMask;
+ //@BP Mod - Custom flags, currently used to enable backface culling on tri-meshes, see btRaycastCallback
+ unsigned int m_flags;
virtual ~RayResultCallback()
{
@@ -192,7 +201,9 @@ public:
:m_closestHitFraction(btScalar(1.)),
m_collisionObject(0),
m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
- m_collisionFilterMask(btBroadphaseProxy::AllFilter)
+ m_collisionFilterMask(btBroadphaseProxy::AllFilter),
+ //@BP Mod
+ m_flags(0)
{
}
@@ -347,7 +358,7 @@ public:
// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback
// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback.
- void convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback) const;
+ void convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = btScalar(0.)) const;
/// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
index 535b61992b0..1dea91a0b0b 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
@@ -19,19 +19,32 @@ subject to the following restrictions:
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
#include "LinearMath/btIDebugDraw.h"
#include "LinearMath/btAabbUtil2.h"
+#include "btManifoldResult.h"
btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
-:btCollisionAlgorithm(ci),
+:btActivatingCollisionAlgorithm(ci,body0,body1),
m_isSwapped(isSwapped),
m_sharedManifold(ci.m_manifold)
{
m_ownsManifold = false;
btCollisionObject* colObj = m_isSwapped? body1 : body0;
+ btAssert (colObj->getCollisionShape()->isCompound());
+
+ btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
+ m_compoundShapeRevision = compoundShape->getUpdateRevision();
+
+ preallocateChildAlgorithms(body0,body1);
+}
+
+void btCompoundCollisionAlgorithm::preallocateChildAlgorithms(btCollisionObject* body0,btCollisionObject* body1)
+{
+ btCollisionObject* colObj = m_isSwapped? body1 : body0;
btCollisionObject* otherObj = m_isSwapped? body0 : body1;
- assert (colObj->getCollisionShape()->isCompound());
+ btAssert (colObj->getCollisionShape()->isCompound());
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
+
int numChildren = compoundShape->getNumChildShapes();
int i;
@@ -46,14 +59,13 @@ m_sharedManifold(ci.m_manifold)
btCollisionShape* tmpShape = colObj->getCollisionShape();
btCollisionShape* childShape = compoundShape->getChildShape(i);
colObj->internalSetTemporaryCollisionShape( childShape );
- m_childCollisionAlgorithms[i] = ci.m_dispatcher1->findAlgorithm(colObj,otherObj,m_sharedManifold);
+ m_childCollisionAlgorithms[i] = m_dispatcher->findAlgorithm(colObj,otherObj,m_sharedManifold);
colObj->internalSetTemporaryCollisionShape( tmpShape );
}
}
}
-
-btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm()
+void btCompoundCollisionAlgorithm::removeChildAlgorithms()
{
int numChildren = m_childCollisionAlgorithms.size();
int i;
@@ -67,6 +79,11 @@ btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm()
}
}
+btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm()
+{
+ removeChildAlgorithms();
+}
+
@@ -167,13 +184,50 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
btCollisionObject* colObj = m_isSwapped? body1 : body0;
btCollisionObject* otherObj = m_isSwapped? body0 : body1;
- assert (colObj->getCollisionShape()->isCompound());
+
+
+ btAssert (colObj->getCollisionShape()->isCompound());
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
+ ///btCompoundShape might have changed:
+ ////make sure the internal child collision algorithm caches are still valid
+ if (compoundShape->getUpdateRevision() != m_compoundShapeRevision)
+ {
+ ///clear and update all
+ removeChildAlgorithms();
+
+ preallocateChildAlgorithms(body0,body1);
+ }
+
+
btDbvt* tree = compoundShape->getDynamicAabbTree();
//use a dynamic aabb tree to cull potential child-overlaps
btCompoundLeafCallback callback(colObj,otherObj,m_dispatcher,dispatchInfo,resultOut,&m_childCollisionAlgorithms[0],m_sharedManifold);
+ ///we need to refresh all contact manifolds
+ ///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep
+ ///so we should add a 'refreshManifolds' in the btCollisionAlgorithm
+ {
+ int i;
+ btManifoldArray manifoldArray;
+ for (i=0;i<m_childCollisionAlgorithms.size();i++)
+ {
+ if (m_childCollisionAlgorithms[i])
+ {
+ m_childCollisionAlgorithms[i]->getAllContactManifolds(manifoldArray);
+ for (int m=0;m<manifoldArray.size();m++)
+ {
+ if (manifoldArray[m]->getNumContacts())
+ {
+ resultOut->setPersistentManifold(manifoldArray[m]);
+ resultOut->refreshContactPoints();
+ resultOut->setPersistentManifold(0);//??necessary?
+ }
+ }
+ manifoldArray.clear();
+ }
+ }
+ }
if (tree)
{
@@ -242,7 +296,7 @@ btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject*
btCollisionObject* colObj = m_isSwapped? body1 : body0;
btCollisionObject* otherObj = m_isSwapped? body0 : body1;
- assert (colObj->getCollisionShape()->isCompound());
+ btAssert (colObj->getCollisionShape()->isCompound());
btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
@@ -285,3 +339,4 @@ btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject*
}
+
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
index 624a3cf10f5..255e0af668c 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef COMPOUND_COLLISION_ALGORITHM_H
#define COMPOUND_COLLISION_ALGORITHM_H
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
@@ -26,16 +26,23 @@ class btDispatcher;
#include "btCollisionCreateFunc.h"
#include "LinearMath/btAlignedObjectArray.h"
class btDispatcher;
+class btCollisionObject;
/// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes
-class btCompoundCollisionAlgorithm : public btCollisionAlgorithm
+class btCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm
{
btAlignedObjectArray<btCollisionAlgorithm*> m_childCollisionAlgorithms;
bool m_isSwapped;
class btPersistentManifold* m_sharedManifold;
bool m_ownsManifold;
+
+ int m_compoundShapeRevision;//to keep track of changes, so that childAlgorithm array can be updated
+
+ void removeChildAlgorithms();
+ void preallocateChildAlgorithms(btCollisionObject* body0,btCollisionObject* body1);
+
public:
btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
index 6d28904cb03..cbc5530732b 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
@@ -27,7 +27,7 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
-: btCollisionAlgorithm(ci),
+: btActivatingCollisionAlgorithm(ci,body0,body1),
m_isSwapped(isSwapped),
m_btConvexTriangleCallback(ci.m_dispatcher1,body0,body1,isSwapped)
{
@@ -72,7 +72,7 @@ btConvexTriangleCallback::~btConvexTriangleCallback()
void btConvexTriangleCallback::clearCache()
{
m_dispatcher->clearManifold(m_manifoldPtr);
-};
+}
@@ -93,7 +93,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
///debug drawing of the overlapping triangles
- if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && m_dispatchInfoPtr->m_debugDraw->getDebugMode() > 0)
+ if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe ))
{
btVector3 color(255,255,0);
btTransform& tr = ob->getWorldTransform();
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
index 34b9a107be9..984a4c39e8e 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef CONVEX_CONCAVE_COLLISION_ALGORITHM_H
#define CONVEX_CONCAVE_COLLISION_ALGORITHM_H
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
@@ -34,8 +34,8 @@ class btConvexTriangleCallback : public btTriangleCallback
btVector3 m_aabbMin;
btVector3 m_aabbMax ;
- btManifoldResult* m_resultOut;
+ btManifoldResult* m_resultOut;
btDispatcher* m_dispatcher;
const btDispatcherInfo* m_dispatchInfoPtr;
btScalar m_collisionMarginTriangle;
@@ -70,7 +70,7 @@ int m_triangleCount;
/// btConvexConcaveCollisionAlgorithm supports collision between convex shapes and (concave) trianges meshes.
-class btConvexConcaveCollisionAlgorithm : public btCollisionAlgorithm
+class btConvexConcaveCollisionAlgorithm : public btActivatingCollisionAlgorithm
{
bool m_isSwapped;
@@ -78,6 +78,7 @@ class btConvexConcaveCollisionAlgorithm : public btCollisionAlgorithm
btConvexTriangleCallback m_btConvexTriangleCallback;
+
public:
btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
index cb830f889be..274c5f5bdc6 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
@@ -38,7 +38,7 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
-#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
@@ -51,6 +51,8 @@ subject to the following restrictions:
btConvexConvexAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
{
+ m_numPerturbationIterations = 0;
+ m_minimumPointsPerturbationThreshold = 3;
m_simplexSolver = simplexSolver;
m_pdSolver = pdSolver;
}
@@ -59,17 +61,22 @@ btConvexConvexAlgorithm::CreateFunc::~CreateFunc()
{
}
-btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
-: btCollisionAlgorithm(ci),
-m_gjkPairDetector(0,0,simplexSolver,pdSolver),
+btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
+: btActivatingCollisionAlgorithm(ci,body0,body1),
+m_simplexSolver(simplexSolver),
+m_pdSolver(pdSolver),
m_ownManifold (false),
m_manifoldPtr(mf),
-m_lowLevelOfDetail(false)
+m_lowLevelOfDetail(false),
+#ifdef USE_SEPDISTANCE_UTIL2
+,m_sepDistance((static_cast<btConvexShape*>(body0->getCollisionShape()))->getAngularMotionDisc(),
+ (static_cast<btConvexShape*>(body1->getCollisionShape()))->getAngularMotionDisc()),
+#endif
+m_numPerturbationIterations(numPerturbationIterations),
+m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
{
(void)body0;
(void)body1;
-
-
}
@@ -90,8 +97,63 @@ void btConvexConvexAlgorithm ::setLowLevelOfDetail(bool useLowLevel)
}
+struct btPerturbedContactResult : public btManifoldResult
+{
+ btManifoldResult* m_originalManifoldResult;
+ btTransform m_transformA;
+ btTransform m_transformB;
+ btTransform m_unPerturbedTransform;
+ bool m_perturbA;
+ btIDebugDraw* m_debugDrawer;
+
+
+ btPerturbedContactResult(btManifoldResult* originalResult,const btTransform& transformA,const btTransform& transformB,const btTransform& unPerturbedTransform,bool perturbA,btIDebugDraw* debugDrawer)
+ :m_originalManifoldResult(originalResult),
+ m_transformA(transformA),
+ m_transformB(transformB),
+ m_perturbA(perturbA),
+ m_unPerturbedTransform(unPerturbedTransform),
+ m_debugDrawer(debugDrawer)
+ {
+ }
+ virtual ~ btPerturbedContactResult()
+ {
+ }
+
+ virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar orgDepth)
+ {
+ btVector3 endPt,startPt;
+ btScalar newDepth;
+ btVector3 newNormal;
+
+ if (m_perturbA)
+ {
+ btVector3 endPtOrg = pointInWorld + normalOnBInWorld*orgDepth;
+ endPt = (m_unPerturbedTransform*m_transformA.inverse())(endPtOrg);
+ newDepth = (endPt - pointInWorld).dot(normalOnBInWorld);
+ startPt = endPt+normalOnBInWorld*newDepth;
+ } else
+ {
+ endPt = pointInWorld + normalOnBInWorld*orgDepth;
+ startPt = (m_unPerturbedTransform*m_transformB.inverse())(pointInWorld);
+ newDepth = (endPt - startPt).dot(normalOnBInWorld);
+
+ }
+
+//#define DEBUG_CONTACTS 1
+#ifdef DEBUG_CONTACTS
+ m_debugDrawer->drawLine(startPt,endPt,btVector3(1,0,0));
+ m_debugDrawer->drawSphere(startPt,0.05,btVector3(0,1,0));
+ m_debugDrawer->drawSphere(endPt,0.05,btVector3(0,0,1));
+#endif //DEBUG_CONTACTS
+
+
+ m_originalManifoldResult->addContactPoint(normalOnBInWorld,startPt,newDepth);
+ }
+};
+extern btScalar gContactBreakingThreshold;
//
// Convex-Convex collision algorithm
@@ -107,39 +169,125 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
}
resultOut->setPersistentManifold(m_manifoldPtr);
-#ifdef USE_BT_GJKEPA
- btConvexShape* shape0(static_cast<btConvexShape*>(body0->getCollisionShape()));
- btConvexShape* shape1(static_cast<btConvexShape*>(body1->getCollisionShape()));
- const btScalar radialmargin(0/*shape0->getMargin()+shape1->getMargin()*/);
- btGjkEpaSolver::sResults results;
- if(btGjkEpaSolver::Collide( shape0,body0->getWorldTransform(),
- shape1,body1->getWorldTransform(),
- radialmargin,results))
- {
- dispatchInfo.m_debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0));
- resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth);
- }
-#else
+ //comment-out next line to test multi-contact generation
+ //resultOut->getPersistentManifold()->clearManifold();
+
btConvexShape* min0 = static_cast<btConvexShape*>(body0->getCollisionShape());
btConvexShape* min1 = static_cast<btConvexShape*>(body1->getCollisionShape());
+
+#ifdef USE_SEPDISTANCE_UTIL2
+ m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(),body1->getWorldTransform());
+ if (!dispatchInfo.m_useConvexConservativeDistanceUtil || m_sepDistance.getConservativeSeparatingDistance()<=0.f)
+#endif //USE_SEPDISTANCE_UTIL2
+
+ {
+
btGjkPairDetector::ClosestPointInput input;
+ btGjkPairDetector gjkPairDetector(min0,min1,m_simplexSolver,m_pdSolver);
//TODO: if (dispatchInfo.m_useContinuous)
- m_gjkPairDetector.setMinkowskiA(min0);
- m_gjkPairDetector.setMinkowskiB(min1);
- input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
- input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
- input.m_stackAlloc = dispatchInfo.m_stackAllocator;
+ gjkPairDetector.setMinkowskiA(min0);
+ gjkPairDetector.setMinkowskiB(min1);
-// input.m_maximumDistanceSquared = btScalar(1e30);
-
+#ifdef USE_SEPDISTANCE_UTIL2
+ if (dispatchInfo.m_useConvexConservativeDistanceUtil)
+ {
+ input.m_maximumDistanceSquared = 1e30f;
+ } else
+#endif //USE_SEPDISTANCE_UTIL2
+ {
+ input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
+ input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
+ }
+
+ input.m_stackAlloc = dispatchInfo.m_stackAllocator;
input.m_transformA = body0->getWorldTransform();
input.m_transformB = body1->getWorldTransform();
+
+ gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
+ btScalar sepDist = gjkPairDetector.getCachedSeparatingDistance()+dispatchInfo.m_convexConservativeDistanceThreshold;
+
+ //now perturbe directions to get multiple contact points
+ btVector3 v0,v1;
+ btVector3 sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis().normalized();
+ btPlaneSpace1(sepNormalWorldSpace,v0,v1);
+ //now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects
- m_gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
+ //perform perturbation when more then 'm_minimumPointsPerturbationThreshold' points
+ if (resultOut->getPersistentManifold()->getNumContacts() < m_minimumPointsPerturbationThreshold)
+ {
+
+ int i;
+
+ bool perturbeA = true;
+ const btScalar angleLimit = 0.125f * SIMD_PI;
+ btScalar perturbeAngle;
+ btScalar radiusA = min0->getAngularMotionDisc();
+ btScalar radiusB = min1->getAngularMotionDisc();
+ if (radiusA < radiusB)
+ {
+ perturbeAngle = gContactBreakingThreshold /radiusA;
+ perturbeA = true;
+ } else
+ {
+ perturbeAngle = gContactBreakingThreshold / radiusB;
+ perturbeA = false;
+ }
+ if ( perturbeAngle > angleLimit )
+ perturbeAngle = angleLimit;
+
+ btTransform unPerturbedTransform;
+ if (perturbeA)
+ {
+ unPerturbedTransform = input.m_transformA;
+ } else
+ {
+ unPerturbedTransform = input.m_transformB;
+ }
+
+ for ( i=0;i<m_numPerturbationIterations;i++)
+ {
+ btQuaternion perturbeRot(v0,perturbeAngle);
+ btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
+ btQuaternion rotq(sepNormalWorldSpace,iterationAngle);
+
+
+ if (perturbeA)
+ {
+ input.m_transformA.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0->getWorldTransform().getBasis());
+ input.m_transformB = body1->getWorldTransform();
+#ifdef DEBUG_CONTACTS
+ dispatchInfo.m_debugDraw->drawTransform(input.m_transformA,10.0);
+#endif //DEBUG_CONTACTS
+ } else
+ {
+ input.m_transformA = body0->getWorldTransform();
+ input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1->getWorldTransform().getBasis());
+#ifdef DEBUG_CONTACTS
+ dispatchInfo.m_debugDraw->drawTransform(input.m_transformB,10.0);
#endif
+ }
+
+ btPerturbedContactResult perturbedResultOut(resultOut,input.m_transformA,input.m_transformB,unPerturbedTransform,perturbeA,dispatchInfo.m_debugDraw);
+ gjkPairDetector.getClosestPoints(input,perturbedResultOut,dispatchInfo.m_debugDraw);
+
+
+ }
+ }
+
+
+
+#ifdef USE_SEPDISTANCE_UTIL2
+ if (dispatchInfo.m_useConvexConservativeDistanceUtil)
+ {
+ m_sepDistance.initSeparatingDistance(gjkPairDetector.getCachedSeparatingAxis(),sepDist,body0->getWorldTransform(),body1->getWorldTransform());
+ }
+#endif //USE_SEPDISTANCE_UTIL2
+
+
+ }
if (m_ownManifold)
{
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
index a0030e6793d..62dd33eb98d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
@@ -16,30 +16,50 @@ subject to the following restrictions:
#ifndef CONVEX_CONVEX_ALGORITHM_H
#define CONVEX_CONVEX_ALGORITHM_H
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
#include "btCollisionCreateFunc.h"
#include "btCollisionDispatcher.h"
+#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil
class btConvexPenetrationDepthSolver;
-///ConvexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations.
-class btConvexConvexAlgorithm : public btCollisionAlgorithm
+///Enabling USE_SEPDISTANCE_UTIL2 requires 100% reliable distance computation. However, when using large size ratios GJK can be imprecise
+///so the distance is not conservative. In that case, enabling this USE_SEPDISTANCE_UTIL2 would result in failing/missing collisions.
+///Either improve GJK for large size ratios (testing a 100 units versus a 0.1 unit object) or only enable the util
+///for certain pairs that have a small size ratio
+///#define USE_SEPDISTANCE_UTIL2 1
+
+///The convexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations between two convex objects.
+///Multiple contact points are calculated by perturbing the orientation of the smallest object orthogonal to the separating normal.
+///This idea was described by Gino van den Bergen in this forum topic http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=4&t=288&p=888#p888
+class btConvexConvexAlgorithm : public btActivatingCollisionAlgorithm
{
- btGjkPairDetector m_gjkPairDetector;
-public:
+#ifdef USE_SEPDISTANCE_UTIL2
+ btConvexSeparatingDistanceUtil m_sepDistance;
+#endif
+ btSimplexSolverInterface* m_simplexSolver;
+ btConvexPenetrationDepthSolver* m_pdSolver;
+
bool m_ownManifold;
btPersistentManifold* m_manifoldPtr;
bool m_lowLevelOfDetail;
+ int m_numPerturbationIterations;
+ int m_minimumPointsPerturbationThreshold;
+
+
+ ///cache separating vector to speedup collision detection
+
public:
- btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver);
+ btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
+
virtual ~btConvexConvexAlgorithm();
@@ -65,9 +85,12 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
+
btConvexPenetrationDepthSolver* m_pdSolver;
btSimplexSolverInterface* m_simplexSolver;
-
+ int m_numPerturbationIterations;
+ int m_minimumPointsPerturbationThreshold;
+
CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver);
virtual ~CreateFunc();
@@ -75,7 +98,7 @@ public:
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConvexAlgorithm));
- return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver);
+ return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
index 391cf6c7bc4..a7b3b163d66 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
@@ -4,8 +4,8 @@ Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
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,
+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.
@@ -22,15 +22,17 @@ subject to the following restrictions:
//#include <stdio.h>
-btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped)
+btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold)
: btCollisionAlgorithm(ci),
m_ownManifold(false),
m_manifoldPtr(mf),
-m_isSwapped(isSwapped)
+m_isSwapped(isSwapped),
+m_numPerturbationIterations(numPerturbationIterations),
+m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
{
btCollisionObject* convexObj = m_isSwapped? col1 : col0;
btCollisionObject* planeObj = m_isSwapped? col0 : col1;
-
+
if (!m_manifoldPtr && m_dispatcher->needsCollision(convexObj,planeObj))
{
m_manifoldPtr = m_dispatcher->getNewManifold(convexObj,planeObj);
@@ -48,30 +50,28 @@ btConvexPlaneCollisionAlgorithm::~btConvexPlaneCollisionAlgorithm()
}
}
-
-
-void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btConvexPlaneCollisionAlgorithm::collideSingleContact (const btQuaternion& perturbeRot, btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
- (void)dispatchInfo;
- (void)resultOut;
- if (!m_manifoldPtr)
- return;
-
- btCollisionObject* convexObj = m_isSwapped? body1 : body0;
+ btCollisionObject* convexObj = m_isSwapped? body1 : body0;
btCollisionObject* planeObj = m_isSwapped? body0: body1;
btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
- bool hasCollision = false;
+ bool hasCollision = false;
const btVector3& planeNormal = planeShape->getPlaneNormal();
const btScalar& planeConstant = planeShape->getPlaneConstant();
- btTransform planeInConvex;
- planeInConvex= convexObj->getWorldTransform().inverse() * planeObj->getWorldTransform();
+
+ btTransform convexWorldTransform = convexObj->getWorldTransform();
btTransform convexInPlaneTrans;
- convexInPlaneTrans= planeObj->getWorldTransform().inverse() * convexObj->getWorldTransform();
-
+ convexInPlaneTrans= planeObj->getWorldTransform().inverse() * convexWorldTransform;
+ //now perturbe the convex-world transform
+ convexWorldTransform.getBasis()*=btMatrix3x3(perturbeRot);
+ btTransform planeInConvex;
+ planeInConvex= convexWorldTransform.inverse() * planeObj->getWorldTransform();
+
btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal);
+
btVector3 vtxInPlane = convexInPlaneTrans(vtx);
btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
@@ -87,6 +87,53 @@ void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0
btVector3 pOnB = vtxInPlaneWorld;
resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance);
}
+}
+
+
+void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+ (void)dispatchInfo;
+ if (!m_manifoldPtr)
+ return;
+
+ btCollisionObject* convexObj = m_isSwapped? body1 : body0;
+ btCollisionObject* planeObj = m_isSwapped? body0: body1;
+
+ btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
+ btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
+
+ bool hasCollision = false;
+ const btVector3& planeNormal = planeShape->getPlaneNormal();
+ const btScalar& planeConstant = planeShape->getPlaneConstant();
+
+ //first perform a collision query with the non-perturbated collision objects
+ {
+ btQuaternion rotq(0,0,0,1);
+ collideSingleContact(rotq,body0,body1,dispatchInfo,resultOut);
+ }
+
+ if (resultOut->getPersistentManifold()->getNumContacts()<m_minimumPointsPerturbationThreshold)
+ {
+ btVector3 v0,v1;
+ btPlaneSpace1(planeNormal,v0,v1);
+ //now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects
+
+ const btScalar angleLimit = 0.125f * SIMD_PI;
+ btScalar perturbeAngle;
+ btScalar radius = convexShape->getAngularMotionDisc();
+ perturbeAngle = gContactBreakingThreshold / radius;
+ if ( perturbeAngle > angleLimit )
+ perturbeAngle = angleLimit;
+
+ btQuaternion perturbeRot(v0,perturbeAngle);
+ for (int i=0;i<m_numPerturbationIterations;i++)
+ {
+ btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
+ btQuaternion rotq(planeNormal,iterationAngle);
+ collideSingleContact(rotq.inverse()*perturbeRot*rotq,body0,body1,dispatchInfo,resultOut);
+ }
+ }
+
if (m_ownManifold)
{
if (m_manifoldPtr->getNumContacts())
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
index 7b258554171..368ca71dda0 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
@@ -4,8 +4,8 @@ Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
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,
+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.
@@ -28,18 +28,22 @@ class btPersistentManifold;
/// Other features are frame-coherency (persistent data) and collision response.
class btConvexPlaneCollisionAlgorithm : public btCollisionAlgorithm
{
- bool m_ownManifold;
+ bool m_ownManifold;
btPersistentManifold* m_manifoldPtr;
- bool m_isSwapped;
-
+ bool m_isSwapped;
+ int m_numPerturbationIterations;
+ int m_minimumPointsPerturbationThreshold;
+
public:
- btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped);
+ btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold);
virtual ~btConvexPlaneCollisionAlgorithm();
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ void collideSingleContact (const btQuaternion& perturbeRot, btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
@@ -52,15 +56,24 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
+ int m_numPerturbationIterations;
+ int m_minimumPointsPerturbationThreshold;
+
+ CreateFunc()
+ : m_numPerturbationIterations(3),
+ m_minimumPointsPerturbationThreshold(3)
+ {
+ }
+
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexPlaneCollisionAlgorithm));
if (!m_swapped)
{
- return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,false);
+ return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,false,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
} else
{
- return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,true);
+ return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,true,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
}
}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp
index 1c317080544..3ae25f109c2 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp
@@ -100,11 +100,10 @@ btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefault
int maxSize = sizeof(btConvexConvexAlgorithm);
int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm);
int maxSize3 = sizeof(btCompoundCollisionAlgorithm);
- int maxSize4 = sizeof(btEmptyAlgorithm);
-
+ int sl = sizeof(btConvexSeparatingDistanceUtil);
+ sl = sizeof(btGjkPairDetector);
int collisionAlgorithmMaxElementSize = btMax(maxSize,maxSize2);
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);
- collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize4);
if (constructionInfo.m_stackAlloc)
{
@@ -289,3 +288,10 @@ btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlg
//failed to find an algorithm
return m_emptyCreateFunc;
}
+
+void btDefaultCollisionConfiguration::setConvexConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold)
+{
+ btConvexConvexAlgorithm::CreateFunc* convexConvex = (btConvexConvexAlgorithm::CreateFunc*) m_convexConvexCreateFunc;
+ convexConvex->m_numPerturbationIterations = numPerturbationIterations;
+ convexConvex->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
+}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h
index df48ee95a18..6d8cab726bd 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h
@@ -33,9 +33,9 @@ struct btDefaultCollisionConstructionInfo
:m_stackAlloc(0),
m_persistentManifoldPool(0),
m_collisionAlgorithmPool(0),
- m_defaultMaxPersistentManifoldPoolSize(65535),
- m_defaultMaxCollisionAlgorithmPoolSize(65535),
- m_defaultStackAllocatorSize(5*1024*1024)
+ m_defaultMaxPersistentManifoldPoolSize(4096),
+ m_defaultMaxCollisionAlgorithmPoolSize(4096),
+ m_defaultStackAllocatorSize(0)
{
}
};
@@ -44,7 +44,7 @@ struct btDefaultCollisionConstructionInfo
///btCollisionConfiguration allows to configure Bullet collision detection
///stack allocator, pool memory allocators
-///todo: describe the meaning
+///@todo: describe the meaning
class btDefaultCollisionConfiguration : public btCollisionConfiguration
{
@@ -111,6 +111,14 @@ public:
virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
+ ///Use this method to allow to generate multiple contact points between at once, between two objects using the generic convex-convex algorithm.
+ ///By default, this feature is disabled for best performance.
+ ///@param numPerturbationIterations controls the number of collision queries. Set it to zero to disable the feature.
+ ///@param minimumPointsPerturbationThreshold is the minimum number of points in the contact cache, above which the feature is disabled
+ ///3 is a good value for both params, if you want to enable the feature. This is because the default contact cache contains a maximum of 4 points, and one collision query at the unperturbed orientation is performed first.
+ ///See Bullet/Demos/CollisionDemo for an example how this feature gathers multiple points.
+ ///@todo we could add a per-object setting of those parameters, for level-of-detail collision detection.
+ void setConvexConvexMultipointIterations(int numPerturbationIterations=3, int minimumPointsPerturbationThreshold = 3);
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.cpp
new file mode 100644
index 00000000000..86141fa6899
--- /dev/null
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.cpp
@@ -0,0 +1,171 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.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 "btGhostObject.h"
+#include "btCollisionWorld.h"
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "LinearMath/btAabbUtil2.h"
+
+btGhostObject::btGhostObject()
+{
+ m_internalType = CO_GHOST_OBJECT;
+}
+
+btGhostObject::~btGhostObject()
+{
+ ///btGhostObject should have been removed from the world, so no overlapping objects
+ btAssert(!m_overlappingObjects.size());
+}
+
+
+void btGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy)
+{
+ btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
+ btAssert(otherObject);
+ ///if this linearSearch becomes too slow (too many overlapping objects) we should add a more appropriate data structure
+ int index = m_overlappingObjects.findLinearSearch(otherObject);
+ if (index==m_overlappingObjects.size())
+ {
+ //not found
+ m_overlappingObjects.push_back(otherObject);
+ }
+}
+
+void btGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy)
+{
+ btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
+ btAssert(otherObject);
+ int index = m_overlappingObjects.findLinearSearch(otherObject);
+ if (index<m_overlappingObjects.size())
+ {
+ m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size()-1];
+ m_overlappingObjects.pop_back();
+ }
+}
+
+
+btPairCachingGhostObject::btPairCachingGhostObject()
+{
+ m_hashPairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();
+}
+
+btPairCachingGhostObject::~btPairCachingGhostObject()
+{
+ m_hashPairCache->~btHashedOverlappingPairCache();
+ btAlignedFree( m_hashPairCache );
+}
+
+void btPairCachingGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy)
+{
+ btBroadphaseProxy*actualThisProxy = thisProxy ? thisProxy : getBroadphaseHandle();
+ btAssert(actualThisProxy);
+
+ btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
+ btAssert(otherObject);
+ int index = m_overlappingObjects.findLinearSearch(otherObject);
+ if (index==m_overlappingObjects.size())
+ {
+ m_overlappingObjects.push_back(otherObject);
+ m_hashPairCache->addOverlappingPair(actualThisProxy,otherProxy);
+ }
+}
+
+void btPairCachingGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy1)
+{
+ btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
+ btBroadphaseProxy* actualThisProxy = thisProxy1 ? thisProxy1 : getBroadphaseHandle();
+ btAssert(actualThisProxy);
+
+ btAssert(otherObject);
+ int index = m_overlappingObjects.findLinearSearch(otherObject);
+ if (index<m_overlappingObjects.size())
+ {
+ m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size()-1];
+ m_overlappingObjects.pop_back();
+ m_hashPairCache->removeOverlappingPair(actualThisProxy,otherProxy,dispatcher);
+ }
+}
+
+
+void btGhostObject::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
+{
+ btTransform convexFromTrans,convexToTrans;
+ convexFromTrans = convexFromWorld;
+ convexToTrans = convexToWorld;
+ btVector3 castShapeAabbMin, castShapeAabbMax;
+ /* Compute AABB that encompasses angular movement */
+ {
+ btVector3 linVel, angVel;
+ btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
+ btTransform R;
+ R.setIdentity ();
+ R.setRotation (convexFromTrans.getRotation());
+ castShape->calculateTemporalAabb (R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
+ }
+
+ /// go over all objects, and if the ray intersects their aabb + cast shape aabb,
+ // do a ray-shape query using convexCaster (CCD)
+ int i;
+ for (i=0;i<m_overlappingObjects.size();i++)
+ {
+ btCollisionObject* collisionObject= m_overlappingObjects[i];
+ //only perform raycast if filterMask matches
+ if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
+ //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
+ btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
+ collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
+ AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
+ btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
+ btVector3 hitNormal;
+ if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
+ {
+ btCollisionWorld::objectQuerySingle(castShape, convexFromTrans,convexToTrans,
+ collisionObject,
+ collisionObject->getCollisionShape(),
+ collisionObject->getWorldTransform(),
+ resultCallback,
+ allowedCcdPenetration);
+ }
+ }
+ }
+
+}
+
+void btGhostObject::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const
+{
+ btTransform rayFromTrans;
+ rayFromTrans.setIdentity();
+ rayFromTrans.setOrigin(rayFromWorld);
+ btTransform rayToTrans;
+ rayToTrans.setIdentity();
+ rayToTrans.setOrigin(rayToWorld);
+
+
+ int i;
+ for (i=0;i<m_overlappingObjects.size();i++)
+ {
+ btCollisionObject* collisionObject= m_overlappingObjects[i];
+ //only perform raycast if filterMask matches
+ if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
+ {
+ btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,
+ collisionObject,
+ collisionObject->getCollisionShape(),
+ collisionObject->getWorldTransform(),
+ resultCallback);
+ }
+ }
+}
+
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.h
new file mode 100644
index 00000000000..95b5750240c
--- /dev/null
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btGhostObject.h
@@ -0,0 +1,174 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.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_GHOST_OBJECT_H
+#define BT_GHOST_OBJECT_H
+
+
+#include "btCollisionObject.h"
+#include "BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h"
+#include "LinearMath/btAlignedAllocator.h"
+#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
+#include "btCollisionWorld.h"
+
+class btConvexShape;
+
+class btDispatcher;
+
+///The btGhostObject can keep track of all objects that are overlapping
+///By default, this overlap is based on the AABB
+///This is useful for creating a character controller, collision sensors/triggers, explosions etc.
+///We plan on adding rayTest and other queries for the btGhostObject
+ATTRIBUTE_ALIGNED16(class) btGhostObject : public btCollisionObject
+{
+protected:
+
+ btAlignedObjectArray<btCollisionObject*> m_overlappingObjects;
+
+public:
+
+ btGhostObject();
+
+ virtual ~btGhostObject();
+
+ void convexSweepTest(const class btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = 0.f) const;
+
+ void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const;
+
+ ///this method is mainly for expert/internal use only.
+ virtual void addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy=0);
+ ///this method is mainly for expert/internal use only.
+ virtual void removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy=0);
+
+ int getNumOverlappingObjects() const
+ {
+ return m_overlappingObjects.size();
+ }
+
+ btCollisionObject* getOverlappingObject(int index)
+ {
+ return m_overlappingObjects[index];
+ }
+
+ const btCollisionObject* getOverlappingObject(int index) const
+ {
+ return m_overlappingObjects[index];
+ }
+
+ btAlignedObjectArray<btCollisionObject*>& getOverlappingPairs()
+ {
+ return m_overlappingObjects;
+ }
+
+ const btAlignedObjectArray<btCollisionObject*> getOverlappingPairs() const
+ {
+ return m_overlappingObjects;
+ }
+
+ //
+ // internal cast
+ //
+
+ static const btGhostObject* upcast(const btCollisionObject* colObj)
+ {
+ if (colObj->getInternalType()==CO_GHOST_OBJECT)
+ return (const btGhostObject*)colObj;
+ return 0;
+ }
+ static btGhostObject* upcast(btCollisionObject* colObj)
+ {
+ if (colObj->getInternalType()==CO_GHOST_OBJECT)
+ return (btGhostObject*)colObj;
+ return 0;
+ }
+
+};
+
+class btPairCachingGhostObject : public btGhostObject
+{
+ btHashedOverlappingPairCache* m_hashPairCache;
+
+public:
+
+ btPairCachingGhostObject();
+
+ virtual ~btPairCachingGhostObject();
+
+ ///this method is mainly for expert/internal use only.
+ virtual void addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy=0);
+
+ virtual void removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy=0);
+
+ btHashedOverlappingPairCache* getOverlappingPairCache()
+ {
+ return m_hashPairCache;
+ }
+
+};
+
+
+
+///The btGhostPairCallback interfaces and forwards adding and removal of overlapping pairs from the btBroadphaseInterface to btGhostObject.
+class btGhostPairCallback : public btOverlappingPairCallback
+{
+
+public:
+ btGhostPairCallback()
+ {
+ }
+
+ virtual ~btGhostPairCallback()
+ {
+
+ }
+
+ virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
+ {
+ btCollisionObject* colObj0 = (btCollisionObject*) proxy0->m_clientObject;
+ btCollisionObject* colObj1 = (btCollisionObject*) proxy1->m_clientObject;
+ btGhostObject* ghost0 = btGhostObject::upcast(colObj0);
+ btGhostObject* ghost1 = btGhostObject::upcast(colObj1);
+ if (ghost0)
+ ghost0->addOverlappingObjectInternal(proxy1, proxy0);
+ if (ghost1)
+ ghost1->addOverlappingObjectInternal(proxy0, proxy1);
+ return 0;
+ }
+
+ virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher)
+ {
+ btCollisionObject* colObj0 = (btCollisionObject*) proxy0->m_clientObject;
+ btCollisionObject* colObj1 = (btCollisionObject*) proxy1->m_clientObject;
+ btGhostObject* ghost0 = btGhostObject::upcast(colObj0);
+ btGhostObject* ghost1 = btGhostObject::upcast(colObj1);
+ if (ghost0)
+ ghost0->removeOverlappingObjectInternal(proxy1,dispatcher,proxy0);
+ if (ghost1)
+ ghost1->removeOverlappingObjectInternal(proxy0,dispatcher,proxy1);
+ return 0;
+ }
+
+ virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy0,btDispatcher* dispatcher)
+ {
+ btAssert(0);
+ //need to keep track of all ghost objects and call them here
+ //m_hashPairCache->removeOverlappingPairsContainingProxy(proxy0,dispatcher);
+ }
+
+
+
+};
+
+#endif \ No newline at end of file
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
index d5b12598be2..f8dfa5b101f 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
@@ -55,7 +55,7 @@ btManifoldResult::btManifoldResult(btCollisionObject* body0,btCollisionObject* b
void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
{
- assert(m_manifoldPtr);
+ btAssert(m_manifoldPtr);
//order in manifold needs to match
if (depth > m_manifoldPtr->getContactBreakingThreshold())
@@ -92,8 +92,8 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
newPt.m_partId1 = m_partId1;
newPt.m_index0 = m_index0;
newPt.m_index1 = m_index1;
-
- ///todo, check this for any side effects
+ //printf("depth=%f\n",depth);
+ ///@todo, check this for any side effects
if (insertIndex >= 0)
{
//const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h
index 5aac9a46f6a..964b6a04483 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h
@@ -45,6 +45,8 @@ class btManifoldResult : public btDiscreteCollisionDetectorInterface::Result
int m_partId1;
int m_index0;
int m_index1;
+
+
public:
btManifoldResult()
@@ -77,6 +79,7 @@ public:
m_index1=index1;
}
+
virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth);
SIMD_FORCE_INLINE void refreshContactPoints()
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
index 9f8e27a4407..0328d0f738f 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
@@ -24,7 +24,8 @@ subject to the following restrictions:
//#include <stdio.h>
#include "LinearMath/btQuickprof.h"
-btSimulationIslandManager::btSimulationIslandManager()
+btSimulationIslandManager::btSimulationIslandManager():
+m_splitIslands(true)
{
}
@@ -43,10 +44,10 @@ void btSimulationIslandManager::findUnions(btDispatcher* /* dispatcher */,btColl
{
{
- btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr();
-
+
for (int i=0;i<colWorld->getPairCache()->getNumOverlappingPairs();i++)
{
+ btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr();
const btBroadphasePair& collisionPair = pairPtr[i];
btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
@@ -143,11 +144,13 @@ class btPersistentManifoldSortPredicate
};
-void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects)
+void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld)
{
BT_PROFILE("islandUnionFindAndQuickSort");
+ btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray();
+
m_islandmanifold.resize(0);
//we are going to sort the unionfind array, and store the element id in the size
@@ -183,7 +186,7 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio
// printf("error in island management\n");
}
- assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
+ btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
if (colObj0->getIslandTag() == islandId)
{
if (colObj0->getActivationState()== ACTIVE_TAG)
@@ -210,7 +213,7 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio
// printf("error in island management\n");
}
- assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
+ btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
if (colObj0->getIslandTag() == islandId)
{
@@ -231,13 +234,14 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio
// printf("error in island management\n");
}
- assert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
+ btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
if (colObj0->getIslandTag() == islandId)
{
if ( colObj0->getActivationState() == ISLAND_SLEEPING)
{
colObj0->setActivationState( WANTS_DEACTIVATION);
+ colObj0->setDeactivationTime(0.f);
}
}
}
@@ -248,11 +252,11 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio
int i;
int maxNumManifolds = dispatcher->getNumManifolds();
-#define SPLIT_ISLANDS 1
-#ifdef SPLIT_ISLANDS
+//#define SPLIT_ISLANDS 1
+//#ifdef SPLIT_ISLANDS
-#endif //SPLIT_ISLANDS
+//#endif //SPLIT_ISLANDS
for (i=0;i<maxNumManifolds ;i++)
@@ -262,7 +266,7 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio
btCollisionObject* colObj0 = static_cast<btCollisionObject*>(manifold->getBody0());
btCollisionObject* colObj1 = static_cast<btCollisionObject*>(manifold->getBody1());
- //todo: check sleeping conditions!
+ ///@todo: check sleeping conditions!
if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) ||
((colObj1) && colObj1->getActivationState() != ISLAND_SLEEPING))
{
@@ -276,24 +280,24 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio
{
colObj0->activate();
}
-#ifdef SPLIT_ISLANDS
- // //filtering for response
- if (dispatcher->needsResponse(colObj0,colObj1))
- m_islandmanifold.push_back(manifold);
-#endif //SPLIT_ISLANDS
+ if(m_splitIslands)
+ {
+ //filtering for response
+ if (dispatcher->needsResponse(colObj0,colObj1))
+ m_islandmanifold.push_back(manifold);
+ }
}
}
}
-//
-// todo: this is random access, it can be walked 'cache friendly'!
-//
-void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback)
+///@todo: this is random access, it can be walked 'cache friendly'!
+void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld, IslandCallback* callback)
{
+ btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray();
- buildIslands(dispatcher,collisionObjects);
+ buildIslands(dispatcher,collisionWorld);
int endIslandIndex=1;
int startIslandIndex;
@@ -301,84 +305,86 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,
BT_PROFILE("processIslands");
-#ifndef SPLIT_ISLANDS
- btPersistentManifold** manifold = dispatcher->getInternalManifoldPointer();
-
- callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, -1);
-#else
- // Sort manifolds, based on islands
- // Sort the vector using predicate and std::sort
- //std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate);
+ if(!m_splitIslands)
+ {
+ btPersistentManifold** manifold = dispatcher->getInternalManifoldPointer();
+ int maxNumManifolds = dispatcher->getNumManifolds();
+ callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, -1);
+ }
+ else
+ {
+ // Sort manifolds, based on islands
+ // Sort the vector using predicate and std::sort
+ //std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate);
- int numManifolds = int (m_islandmanifold.size());
+ int numManifolds = int (m_islandmanifold.size());
- //we should do radix sort, it it much faster (O(n) instead of O (n log2(n))
- m_islandmanifold.quickSort(btPersistentManifoldSortPredicate());
+ //we should do radix sort, it it much faster (O(n) instead of O (n log2(n))
+ m_islandmanifold.quickSort(btPersistentManifoldSortPredicate());
- //now process all active islands (sets of manifolds for now)
+ //now process all active islands (sets of manifolds for now)
- int startManifoldIndex = 0;
- int endManifoldIndex = 1;
+ int startManifoldIndex = 0;
+ int endManifoldIndex = 1;
- //int islandId;
+ //int islandId;
-
+
-// printf("Start Islands\n");
+ // printf("Start Islands\n");
- //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated
- for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
- {
- int islandId = getUnionFind().getElement(startIslandIndex).m_id;
+ //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated
+ for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
+ {
+ int islandId = getUnionFind().getElement(startIslandIndex).m_id;
- bool islandSleeping = false;
-
- for (endIslandIndex = startIslandIndex;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
- {
- int i = getUnionFind().getElement(endIslandIndex).m_sz;
- btCollisionObject* colObj0 = collisionObjects[i];
- m_islandBodies.push_back(colObj0);
- if (!colObj0->isActive())
- islandSleeping = true;
- }
-
+ bool islandSleeping = false;
+
+ for (endIslandIndex = startIslandIndex;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
+ {
+ int i = getUnionFind().getElement(endIslandIndex).m_sz;
+ btCollisionObject* colObj0 = collisionObjects[i];
+ m_islandBodies.push_back(colObj0);
+ if (!colObj0->isActive())
+ islandSleeping = true;
+ }
+
- //find the accompanying contact manifold for this islandId
- int numIslandManifolds = 0;
- btPersistentManifold** startManifold = 0;
+ //find the accompanying contact manifold for this islandId
+ int numIslandManifolds = 0;
+ btPersistentManifold** startManifold = 0;
- if (startManifoldIndex<numManifolds)
- {
- int curIslandId = getIslandId(m_islandmanifold[startManifoldIndex]);
- if (curIslandId == islandId)
+ if (startManifoldIndex<numManifolds)
{
- startManifold = &m_islandmanifold[startManifoldIndex];
-
- for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(m_islandmanifold[endManifoldIndex]));endManifoldIndex++)
+ int curIslandId = getIslandId(m_islandmanifold[startManifoldIndex]);
+ if (curIslandId == islandId)
{
+ startManifold = &m_islandmanifold[startManifoldIndex];
+
+ for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(m_islandmanifold[endManifoldIndex]));endManifoldIndex++)
+ {
+ }
+ /// Process the actual simulation, only if not sleeping/deactivated
+ numIslandManifolds = endManifoldIndex-startManifoldIndex;
}
- /// Process the actual simulation, only if not sleeping/deactivated
- numIslandManifolds = endManifoldIndex-startManifoldIndex;
+
}
- }
+ if (!islandSleeping)
+ {
+ callback->ProcessIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId);
+ // printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds);
+ }
+
+ if (numIslandManifolds)
+ {
+ startManifoldIndex = endManifoldIndex;
+ }
- if (!islandSleeping)
- {
- callback->ProcessIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId);
-// printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds);
- }
-
- if (numIslandManifolds)
- {
- startManifoldIndex = endManifoldIndex;
+ m_islandBodies.resize(0);
}
-
- m_islandBodies.resize(0);
- }
-#endif //SPLIT_ISLANDS
-
+ } // else if(!splitIslands)
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h
index 5f4d54cd803..d059f5d6b0d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h
@@ -19,7 +19,7 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btUnionFind.h"
#include "btCollisionCreateFunc.h"
#include "LinearMath/btAlignedObjectArray.h"
-
+#include "btCollisionObject.h"
class btCollisionObject;
class btCollisionWorld;
@@ -35,6 +35,7 @@ class btSimulationIslandManager
btAlignedObjectArray<btPersistentManifold*> m_islandmanifold;
btAlignedObjectArray<btCollisionObject* > m_islandBodies;
+ bool m_splitIslands;
public:
btSimulationIslandManager();
@@ -61,9 +62,18 @@ public:
virtual void ProcessIsland(btCollisionObject** bodies,int numBodies,class btPersistentManifold** manifolds,int numManifolds, int islandId) = 0;
};
- void buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback);
+ void buildAndProcessIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld, IslandCallback* callback);
+
+ void buildIslands(btDispatcher* dispatcher,btCollisionWorld* colWorld);
- void buildIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects);
+ bool getSplitIslands()
+ {
+ return m_splitIslands;
+ }
+ void setSplitIslands(bool doSplitIslands)
+ {
+ m_splitIslands = doSplitIslands;
+ }
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
index 1e4bbce451d..8df876928c1 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
@@ -21,7 +21,7 @@ subject to the following restrictions:
//#include <stdio.h>
btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped)
-: btCollisionAlgorithm(ci),
+: btActivatingCollisionAlgorithm(ci,col0,col1),
m_ownManifold(false),
m_manifoldPtr(mf),
m_isSwapped(isSwapped)
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h
index 158f0ffcc74..47111d1c4af 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef SPHERE_BOX_COLLISION_ALGORITHM_H
#define SPHERE_BOX_COLLISION_ALGORITHM_H
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
class btPersistentManifold;
@@ -26,7 +26,7 @@ class btPersistentManifold;
/// btSphereBoxCollisionAlgorithm provides sphere-box collision detection.
/// Other features are frame-coherency (persistent data) and collision response.
-class btSphereBoxCollisionAlgorithm : public btCollisionAlgorithm
+class btSphereBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm
{
bool m_ownManifold;
btPersistentManifold* m_manifoldPtr;
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
index c2b13f5903f..5c4e78fe518 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
@@ -19,7 +19,7 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1)
-: btCollisionAlgorithm(ci),
+: btActivatingCollisionAlgorithm(ci,col0,col1),
m_ownManifold(false),
m_manifoldPtr(mf)
{
@@ -78,7 +78,7 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0
}
///point on A (worldspace)
- btVector3 pos0 = col0->getWorldTransform().getOrigin() - radius0 * normalOnSurfaceB;
+ ///btVector3 pos0 = col0->getWorldTransform().getOrigin() - radius0 * normalOnSurfaceB;
///point on B (worldspace)
btVector3 pos1 = col1->getWorldTransform().getOrigin() + radius1* normalOnSurfaceB;
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h
index afdc2ee7fa0..7d07512ca66 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef SPHERE_SPHERE_COLLISION_ALGORITHM_H
#define SPHERE_SPHERE_COLLISION_ALGORITHM_H
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
#include "btCollisionDispatcher.h"
@@ -26,7 +26,7 @@ class btPersistentManifold;
/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection.
/// Other features are frame-coherency (persistent data) and collision response.
/// Also provides the most basic sample for custom/user btCollisionAlgorithm
-class btSphereSphereCollisionAlgorithm : public btCollisionAlgorithm
+class btSphereSphereCollisionAlgorithm : public btActivatingCollisionAlgorithm
{
bool m_ownManifold;
btPersistentManifold* m_manifoldPtr;
@@ -35,7 +35,7 @@ public:
btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
btSphereSphereCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
- : btCollisionAlgorithm(ci) {}
+ : btActivatingCollisionAlgorithm(ci) {}
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
index fdbd4abef27..2d5efcf56ba 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
@@ -22,7 +22,7 @@ subject to the following restrictions:
btSphereTriangleCollisionAlgorithm::btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1,bool swapped)
-: btCollisionAlgorithm(ci),
+: btActivatingCollisionAlgorithm(ci,col0,col1),
m_ownManifold(false),
m_manifoldPtr(mf),
m_swapped(swapped)
@@ -56,10 +56,10 @@ void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* co
/// report a contact. internally this will be kept persistent, and contact reduction is done
resultOut->setPersistentManifold(m_manifoldPtr);
- SphereTriangleDetector detector(sphere,triangle);
+ SphereTriangleDetector detector(sphere,triangle, m_manifoldPtr->getContactBreakingThreshold());
btDiscreteCollisionDetectorInterface::ClosestPointInput input;
- input.m_maximumDistanceSquared = btScalar(1e30);//todo: tighter bounds
+ input.m_maximumDistanceSquared = btScalar(1e30);///@todo: tighter bounds
input.m_transformA = sphereObj->getWorldTransform();
input.m_transformB = triObj->getWorldTransform();
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
index bbaf228c44c..606c3635ae9 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
#define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
class btPersistentManifold;
@@ -25,7 +25,7 @@ class btPersistentManifold;
/// btSphereSphereCollisionAlgorithm provides sphere-sphere collision detection.
/// Other features are frame-coherency (persistent data) and collision response.
/// Also provides the most basic sample for custom/user btCollisionAlgorithm
-class btSphereTriangleCollisionAlgorithm : public btCollisionAlgorithm
+class btSphereTriangleCollisionAlgorithm : public btActivatingCollisionAlgorithm
{
bool m_ownManifold;
btPersistentManifold* m_manifoldPtr;
@@ -35,7 +35,7 @@ public:
btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool swapped);
btSphereTriangleCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
- : btCollisionAlgorithm(ci) {}
+ : btActivatingCollisionAlgorithm(ci) {}
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp
index bb01b60fa85..c561df06109 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.cpp
@@ -14,8 +14,6 @@ subject to the following restrictions:
*/
#include "btUnionFind.h"
-#include <assert.h>
-
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h
index 820c8bc858e..e105ecbff18 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btUnionFind.h
@@ -98,8 +98,8 @@ class btUnionFind
int find(int x)
{
- //assert(x < m_N);
- //assert(x >= 0);
+ //btAssert(x < m_N);
+ //btAssert(x >= 0);
while (x != m_elements[x].m_id)
{
@@ -110,8 +110,8 @@ class btUnionFind
m_elements[x].m_id = m_elements[m_elements[x].m_id].m_id;
#endif //
x = m_elements[x].m_id;
- //assert(x < m_N);
- //assert(x >= 0);
+ //btAssert(x < m_N);
+ //btAssert(x >= 0);
}
return x;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h
index 4d4fbefea37..14502d485dc 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h
@@ -19,7 +19,7 @@ subject to the following restrictions:
#include "btPolyhedralConvexShape.h"
#include "btCollisionMargin.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
-#include "LinearMath/btPoint3.h"
+#include "LinearMath/btVector3.h"
#include "LinearMath/btMinMax.h"
///The btBoxShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space.
@@ -45,8 +45,6 @@ public:
}
- virtual int getShapeType() const { return BOX_SHAPE_PROXYTYPE;}
-
virtual btVector3 localGetSupportingVertex(const btVector3& vec) const
{
btVector3 halfExtents = getHalfExtentsWithoutMargin();
@@ -82,8 +80,10 @@ public:
}
- btBoxShape( const btVector3& boxHalfExtents)
+ btBoxShape( const btVector3& boxHalfExtents)
+ : btPolyhedralConvexShape()
{
+ m_shapeType = BOX_SHAPE_PROXYTYPE;
btVector3 margin(getMargin(),getMargin(),getMargin());
m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;
};
@@ -117,7 +117,7 @@ public:
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
- virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const
+ virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const
{
//this plane might not be aligned...
btVector4 plane ;
@@ -161,36 +161,30 @@ public:
switch (i)
{
case 0:
- plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.));
- plane[3] = -halfExtents.x();
+ plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x());
break;
case 1:
- plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.));
- plane[3] = -halfExtents.x();
+ plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x());
break;
case 2:
- plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.));
- plane[3] = -halfExtents.y();
+ plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y());
break;
case 3:
- plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.));
- plane[3] = -halfExtents.y();
+ plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y());
break;
case 4:
- plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.));
- plane[3] = -halfExtents.z();
+ plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z());
break;
case 5:
- plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
- plane[3] = -halfExtents.z();
+ plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z());
break;
default:
- assert(0);
+ btAssert(0);
}
}
- virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const
+ virtual void getEdge(int i,btVector3& pa,btVector3& pb) const
//virtual void getEdge(int i,Edge& edge) const
{
int edgeVert0 = 0;
@@ -261,7 +255,7 @@ public:
- virtual bool isInside(const btPoint3& pt,btScalar tolerance) const
+ virtual bool isInside(const btVector3& pt,btScalar tolerance) const
{
btVector3 halfExtents = getHalfExtentsWithoutMargin();
@@ -312,7 +306,7 @@ public:
penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
break;
default:
- assert(0);
+ btAssert(0);
}
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
index 819f6f7f97d..68ff5e2d7bb 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
@@ -26,6 +26,7 @@ m_bvh(0),
m_useQuantizedAabbCompression(useQuantizedAabbCompression),
m_ownsBvh(false)
{
+ m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
//construct bvh from meshInterface
#ifndef DISABLE_BVH
@@ -57,6 +58,7 @@ m_bvh(0),
m_useQuantizedAabbCompression(useQuantizedAabbCompression),
m_ownsBvh(false)
{
+ m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
//construct bvh from meshInterface
#ifndef DISABLE_BVH
@@ -141,10 +143,19 @@ void btBvhTriangleMeshShape::performRaycast (btTriangleCallback* callback, const
for (int j=2;j>=0;j--)
{
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
-
- btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
-
- m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
+
+ if (type == PHY_FLOAT)
+ {
+ float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
+
+ m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
+ }
+ else
+ {
+ double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
+
+ m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ());
+ }
}
/* Perform ray vs. triangle collision here */
@@ -202,9 +213,18 @@ void btBvhTriangleMeshShape::performConvexcast (btTriangleCallback* callback, co
{
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
- btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
-
- m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
+ if (type == PHY_FLOAT)
+ {
+ float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
+
+ m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
+ }
+ else
+ {
+ double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
+
+ m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ());
+ }
}
/* Perform ray vs. triangle collision here */
@@ -279,12 +299,24 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co
#ifdef DEBUG_TRIANGLE_MESH
printf("%d ,",graphicsindex);
#endif //DEBUG_TRIANGLE_MESH
- btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
-
- m_triangle[j] = btVector3(
- graphicsbase[0]*meshScaling.getX(),
- graphicsbase[1]*meshScaling.getY(),
- graphicsbase[2]*meshScaling.getZ());
+ if (type == PHY_FLOAT)
+ {
+ float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
+
+ m_triangle[j] = btVector3(
+ graphicsbase[0]*meshScaling.getX(),
+ graphicsbase[1]*meshScaling.getY(),
+ graphicsbase[2]*meshScaling.getZ());
+ }
+ else
+ {
+ double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
+
+ m_triangle[j] = btVector3(
+ btScalar(graphicsbase[0])*meshScaling.getX(),
+ btScalar(graphicsbase[1])*meshScaling.getY(),
+ btScalar(graphicsbase[2])*meshScaling.getZ());
+ }
#ifdef DEBUG_TRIANGLE_MESH
printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z());
#endif //DEBUG_TRIANGLE_MESH
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
index 6e587340dc1..cb2c326574e 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
@@ -37,7 +37,7 @@ public:
BT_DECLARE_ALIGNED_ALLOCATOR();
- btBvhTriangleMeshShape() :btTriangleMeshShape(0),m_bvh(0),m_ownsBvh(false) {};
+ btBvhTriangleMeshShape() : btTriangleMeshShape(0),m_bvh(0),m_ownsBvh(false) {m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;};
btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true);
///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb
@@ -50,10 +50,7 @@ public:
return m_ownsBvh;
}
- virtual int getShapeType() const
- {
- return TRIANGLE_MESH_SHAPE_PROXYTYPE;
- }
+
void performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget);
void performConvexcast (btTriangleCallback* callback, const btVector3& boxSource, const btVector3& boxTarget, const btVector3& boxMin, const btVector3& boxMax);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp
index 26ba276b900..60a96a542f9 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp
@@ -19,8 +19,9 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
#include "LinearMath/btQuaternion.h"
-btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height)
+btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInternalShape ()
{
+ m_shapeType = CAPSULE_SHAPE_PROXYTYPE;
m_upAxis = 1;
m_implicitShapeDimensions.setValue(radius,0.5f*height,radius);
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h
index d4b046d40c9..828c1b3a565 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h
@@ -30,7 +30,7 @@ protected:
protected:
///only used for btCapsuleShapeZ and btCapsuleShapeX subclasses.
- btCapsuleShape() {};
+ btCapsuleShape() : btConvexInternalShape() {m_shapeType = CAPSULE_SHAPE_PROXYTYPE;};
public:
btCapsuleShape(btScalar radius,btScalar height);
@@ -43,15 +43,13 @@ public:
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
- virtual int getShapeType() const { return CAPSULE_SHAPE_PROXYTYPE; }
-
virtual void getAabb (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
{
btVector3 halfExtents(getRadius(),getRadius(),getRadius());
halfExtents[m_upAxis] = getRadius() + getHalfHeight();
halfExtents += btVector3(getMargin(),getMargin(),getMargin());
btMatrix3x3 abs_b = t.getBasis().absolute();
- btPoint3 center = t.getOrigin();
+ btVector3 center = t.getOrigin();
btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
aabbMin = center - extent;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp
index 39e621aa946..d242cba1b72 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.cpp
@@ -16,6 +16,9 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
+btScalar gContactThresholdFactor=btScalar(0.02);
+
+
/*
Make sure this dummy function never changes so that it
can be used by probes that are checking whether the
@@ -42,8 +45,13 @@ void btCollisionShape::getBoundingSphere(btVector3& center,btScalar& radius) con
center = (aabbMin+aabbMax)*btScalar(0.5);
}
+btScalar btCollisionShape::getContactBreakingThreshold() const
+{
+ return getAngularMotionDisc() * gContactThresholdFactor;
+}
btScalar btCollisionShape::getAngularMotionDisc() const
{
+ ///@todo cache this value, to improve performance
btVector3 center;
btScalar disc;
getBoundingSphere(center,disc);
@@ -65,7 +73,7 @@ void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans,const b
// add linear motion
btVector3 linMotion = linvel*timeStep;
- //todo: simd would have a vector max/min operation, instead of per-element access
+ ///@todo: simd would have a vector max/min operation, instead of per-element access
if (linMotion.x() > btScalar(0.))
temporalAabbMaxx += linMotion.x();
else
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h
index 3a352b90777..1f4b9bec647 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h
@@ -19,20 +19,21 @@ subject to the following restrictions:
#include "LinearMath/btTransform.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btMatrix3x3.h"
-#include "LinearMath/btPoint3.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types
///The btCollisionShape class provides an interface for collision shapes that can be shared among btCollisionObjects.
class btCollisionShape
{
-
+protected:
+ int m_shapeType;
void* m_userPointer;
public:
- btCollisionShape() : m_userPointer(0)
+ btCollisionShape() : m_shapeType (INVALID_SHAPE_PROXYTYPE), m_userPointer(0)
{
}
+
virtual ~btCollisionShape()
{
}
@@ -45,6 +46,8 @@ public:
///getAngularMotionDisc returns the maximus radius needed for Conservative Advancement to handle time-of-impact with rotations.
virtual btScalar getAngularMotionDisc() const;
+ virtual btScalar getContactBreakingThreshold() const;
+
///calculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0..timeStep)
///result is conservative
@@ -76,7 +79,7 @@ public:
return btBroadphaseProxy::isInfinite(getShapeType());
}
- virtual int getShapeType() const=0;
+
virtual void setLocalScaling(const btVector3& scaling) =0;
virtual const btVector3& getLocalScaling() const =0;
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const = 0;
@@ -87,13 +90,13 @@ public:
#endif //__SPU__
-
+ int getShapeType() const { return m_shapeType; }
virtual void setMargin(btScalar margin) = 0;
virtual btScalar getMargin() const = 0;
///optional user data pointer
- void setUserPointer(void* userPtr)
+ void setUserPointer(void* userPtr)
{
m_userPointer = userPtr;
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp
index 997361a5069..9c2b04d18fa 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp
@@ -17,16 +17,22 @@ subject to the following restrictions:
#include "btCollisionShape.h"
#include "BulletCollision/BroadphaseCollision/btDbvt.h"
-btCompoundShape::btCompoundShape()
-:m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)),
+btCompoundShape::btCompoundShape(bool enableDynamicAabbTree)
+: m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)),
m_localAabbMax(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)),
m_collisionMargin(btScalar(0.)),
m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
-m_dynamicAabbTree(0)
+m_dynamicAabbTree(0),
+m_updateRevision(1)
{
- void* mem = btAlignedAlloc(sizeof(btDbvt),16);
- m_dynamicAabbTree = new(mem) btDbvt();
- btAssert(mem==m_dynamicAabbTree);
+ m_shapeType = COMPOUND_SHAPE_PROXYTYPE;
+
+ if (enableDynamicAabbTree)
+ {
+ void* mem = btAlignedAlloc(sizeof(btDbvt),16);
+ m_dynamicAabbTree = new(mem) btDbvt();
+ btAssert(mem==m_dynamicAabbTree);
+ }
}
@@ -41,6 +47,7 @@ btCompoundShape::~btCompoundShape()
void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape)
{
+ m_updateRevision++;
//m_childTransforms.push_back(localTransform);
//m_childShapes.push_back(shape);
btCompoundShapeChild child;
@@ -49,6 +56,7 @@ void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisio
child.m_childShapeType = shape->getShapeType();
child.m_childMargin = shape->getMargin();
+
//extend the local aabbMin/aabbMax
btVector3 localAabbMin,localAabbMax;
shape->getAabb(localTransform,localAabbMin,localAabbMax);
@@ -72,10 +80,29 @@ void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisio
}
m_children.push_back(child);
+
+}
+
+void btCompoundShape::updateChildTransform(int childIndex, const btTransform& newChildTransform)
+{
+ m_children[childIndex].m_transform = newChildTransform;
+
+ if (m_dynamicAabbTree)
+ {
+ ///update the dynamic aabb tree
+ btVector3 localAabbMin,localAabbMax;
+ m_children[childIndex].m_childShape->getAabb(newChildTransform,localAabbMin,localAabbMax);
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
+ int index = m_children.size()-1;
+ m_dynamicAabbTree->update(m_children[childIndex].m_node,bounds);
+ }
+
+ recalculateLocalAabb();
}
void btCompoundShape::removeChildShapeByIndex(int childShapeIndex)
{
+ m_updateRevision++;
btAssert(childShapeIndex >=0 && childShapeIndex < m_children.size());
if (m_dynamicAabbTree)
{
@@ -86,8 +113,11 @@ void btCompoundShape::removeChildShapeByIndex(int childShapeIndex)
}
+
+
void btCompoundShape::removeChildShape(btCollisionShape* shape)
{
+ m_updateRevision++;
// Find the children containing the shape specified, and remove those children.
//note: there might be multiple children using the same shape!
for(int i = m_children.size()-1; i >= 0 ; i--)
@@ -97,6 +127,8 @@ void btCompoundShape::removeChildShape(btCollisionShape* shape)
m_children.swap(i,m_children.size()-1);
m_children.pop_back();
//remove it from the m_dynamicAabbTree too
+ //@todo: this leads to problems due to caching in the btCompoundCollisionAlgorithm
+ //so effectively, removeChildShape is broken at the moment
//m_dynamicAabbTree->remove(m_aabbProxies[i]);
//m_aabbProxies.swap(i,m_children.size()-1);
//m_aabbProxies.pop_back();
@@ -112,6 +144,7 @@ void btCompoundShape::recalculateLocalAabb()
{
// Recalculate the local aabb
// Brute force, it iterates over all the shapes left.
+
m_localAabbMin = btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30));
m_localAabbMax = btVector3(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
@@ -134,19 +167,27 @@ void btCompoundShape::recalculateLocalAabb()
void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
{
btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
- localHalfExtents += btVector3(getMargin(),getMargin(),getMargin());
btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
+
+ //avoid an illegal AABB when there are no children
+ if (!m_children.size())
+ {
+ localHalfExtents.setValue(0,0,0);
+ localCenter.setValue(0,0,0);
+ }
+ localHalfExtents += btVector3(getMargin(),getMargin(),getMargin());
+
btMatrix3x3 abs_b = trans.getBasis().absolute();
- btPoint3 center = trans(localCenter);
+ btVector3 center = trans(localCenter);
btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
abs_b[1].dot(localHalfExtents),
abs_b[2].dot(localHalfExtents));
aabbMin = center-extent;
aabbMax = center+extent;
-
+
}
void btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
@@ -178,7 +219,9 @@ void btCompoundShape::calculatePrincipalAxisTransform(btScalar* masses, btTransf
btScalar totalMass = 0;
btVector3 center(0, 0, 0);
- for (int k = 0; k < n; k++)
+ int k;
+
+ for (k = 0; k < n; k++)
{
center += m_children[k].m_transform.getOrigin() * masses[k];
totalMass += masses[k];
@@ -187,7 +230,7 @@ void btCompoundShape::calculatePrincipalAxisTransform(btScalar* masses, btTransf
principal.setOrigin(center);
btMatrix3x3 tensor(0, 0, 0, 0, 0, 0, 0, 0, 0);
- for (int k = 0; k < n; k++)
+ for ( k = 0; k < n; k++)
{
btVector3 i;
m_children[k].m_childShape->calculateLocalInertia(masses[k], i);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h
index 3624749f768..434860c8633 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.h
@@ -46,23 +46,26 @@ SIMD_FORCE_INLINE bool operator==(const btCompoundShapeChild& c1, const btCompou
c1.m_childMargin == c2.m_childMargin );
}
-/// btCompoundShape allows to store multiple other btCollisionShapes
+/// The btCompoundShape allows to store multiple other btCollisionShapes
/// This allows for moving concave collision objects. This is more general then the static concave btBvhTriangleMeshShape.
+/// It has an (optional) dynamic aabb tree to accelerate early rejection tests.
+/// @todo: This aabb tree can also be use to speed up ray tests on btCompoundShape, see http://code.google.com/p/bullet/issues/detail?id=25
+/// Currently, removal of child shapes is only supported when disabling the aabb tree (pass 'false' in the constructor of btCompoundShape)
ATTRIBUTE_ALIGNED16(class) btCompoundShape : public btCollisionShape
{
- //btAlignedObjectArray<btTransform> m_childTransforms;
- //btAlignedObjectArray<btCollisionShape*> m_childShapes;
btAlignedObjectArray<btCompoundShapeChild> m_children;
btVector3 m_localAabbMin;
btVector3 m_localAabbMax;
- //btOptimizedBvh* m_aabbTree;
btDbvt* m_dynamicAabbTree;
+ ///increment m_updateRevision when adding/removing/replacing child shapes, so that some caches can be updated
+ int m_updateRevision;
+
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
- btCompoundShape();
+ btCompoundShape(bool enableDynamicAabbTree = true);
virtual ~btCompoundShape();
@@ -88,15 +91,18 @@ public:
return m_children[index].m_childShape;
}
- btTransform getChildTransform(int index)
+ btTransform& getChildTransform(int index)
{
return m_children[index].m_transform;
}
- const btTransform getChildTransform(int index) const
+ const btTransform& getChildTransform(int index) const
{
return m_children[index].m_transform;
}
+ ///set a new transform for a child, and update internal data structures (local aabb and dynamic tree)
+ void updateChildTransform(int childIndex, const btTransform& newChildTransform);
+
btCompoundShapeChild* getChildList()
{
@@ -121,8 +127,6 @@ public:
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
- virtual int getShapeType() const { return COMPOUND_SHAPE_PROXYTYPE;}
-
virtual void setMargin(btScalar margin)
{
m_collisionMargin = margin;
@@ -151,6 +155,10 @@ public:
///of the collision object by the principal transform.
void calculatePrincipalAxisTransform(btScalar* masses, btTransform& principal, btVector3& inertia) const;
+ int getUpdateRevision() const
+ {
+ return m_updateRevision;
+ }
private:
btScalar m_collisionMargin;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h
index f3f57206ab7..30065d55a12 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h
@@ -20,6 +20,16 @@ subject to the following restrictions:
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "btTriangleCallback.h"
+/// PHY_ScalarType enumerates possible scalar types.
+/// See the btStridingMeshInterface or btHeightfieldTerrainShape for its use
+typedef enum PHY_ScalarType {
+ PHY_FLOAT,
+ PHY_DOUBLE,
+ PHY_INTEGER,
+ PHY_SHORT,
+ PHY_FIXEDPOINT88,
+ PHY_UCHAR
+} PHY_ScalarType;
///The btConcaveShape class provides an interface for non-moving (static) concave shapes.
///It has been implemented by the btStaticPlaneShape, btBvhTriangleMeshShape and btHeightfieldTerrainShape.
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp
index 207b3024bc3..d887be61ada 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.cpp
@@ -14,14 +14,14 @@ subject to the following restrictions:
*/
#include "btConeShape.h"
-#include "LinearMath/btPoint3.h"
-btConeShape::btConeShape (btScalar radius,btScalar height):
+btConeShape::btConeShape (btScalar radius,btScalar height): btConvexInternalShape (),
m_radius (radius),
m_height(height)
{
+ m_shapeType = CONE_SHAPE_PROXYTYPE;
setConeUpIndex(1);
btVector3 halfExtents;
m_sinAngle = (m_radius / btSqrt(m_radius * m_radius + m_height * m_height));
@@ -60,7 +60,7 @@ void btConeShape::setConeUpIndex(int upIndex)
m_coneIndices[2] = 1;
break;
default:
- assert(0);
+ btAssert(0);
};
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h
index 685369742e4..1869893f37a 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h
@@ -69,9 +69,6 @@ public:
}
-
- virtual int getShapeType() const { return CONE_SHAPE_PROXYTYPE; }
-
virtual const char* getName()const
{
return "Cone";
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp
index 2596858bc3a..2b067367767 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp
@@ -19,16 +19,17 @@ subject to the following restrictions:
-btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride)
+btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride) : btPolyhedralConvexShape ()
{
- m_points.resize(numPoints);
+ m_shapeType = CONVEX_HULL_SHAPE_PROXYTYPE;
+ m_unscaledPoints.resize(numPoints);
unsigned char* pointsBaseAddress = (unsigned char*)points;
for (int i=0;i<numPoints;i++)
{
- btPoint3* point = (btPoint3*)(pointsBaseAddress + i*stride);
- m_points[i] = point[0];
+ btVector3* point = (btVector3*)(pointsBaseAddress + i*stride);
+ m_unscaledPoints[i] = point[0];
}
recalcLocalAabb();
@@ -43,9 +44,9 @@ void btConvexHullShape::setLocalScaling(const btVector3& scaling)
recalcLocalAabb();
}
-void btConvexHullShape::addPoint(const btPoint3& point)
+void btConvexHullShape::addPoint(const btVector3& point)
{
- m_points.push_back(point);
+ m_unscaledPoints.push_back(point);
recalcLocalAabb();
}
@@ -67,9 +68,9 @@ btVector3 btConvexHullShape::localGetSupportingVertexWithoutMargin(const btVecto
}
- for (int i=0;i<m_points.size();i++)
+ for (int i=0;i<m_unscaledPoints.size();i++)
{
- btPoint3 vtx = m_points[i] * m_localScaling;
+ btVector3 vtx = m_unscaledPoints[i] * m_localScaling;
newDot = vec.dot(vtx);
if (newDot > maxDot)
@@ -91,9 +92,9 @@ void btConvexHullShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const
supportVerticesOut[i][3] = btScalar(-1e30);
}
}
- for (int i=0;i<m_points.size();i++)
+ for (int i=0;i<m_unscaledPoints.size();i++)
{
- btPoint3 vtx = m_points[i] * m_localScaling;
+ btVector3 vtx = getScaledPoint(i);
for (int j=0;j<numVectors;j++)
{
@@ -144,26 +145,26 @@ btVector3 btConvexHullShape::localGetSupportingVertex(const btVector3& vec)const
//Please note that you can debug-draw btConvexHullShape with the Raytracer Demo
int btConvexHullShape::getNumVertices() const
{
- return m_points.size();
+ return m_unscaledPoints.size();
}
int btConvexHullShape::getNumEdges() const
{
- return m_points.size();
+ return m_unscaledPoints.size();
}
-void btConvexHullShape::getEdge(int i,btPoint3& pa,btPoint3& pb) const
+void btConvexHullShape::getEdge(int i,btVector3& pa,btVector3& pb) const
{
- int index0 = i%m_points.size();
- int index1 = (i+1)%m_points.size();
- pa = m_points[index0]*m_localScaling;
- pb = m_points[index1]*m_localScaling;
+ int index0 = i%m_unscaledPoints.size();
+ int index1 = (i+1)%m_unscaledPoints.size();
+ pa = getScaledPoint(index0);
+ pb = getScaledPoint(index1);
}
-void btConvexHullShape::getVertex(int i,btPoint3& vtx) const
+void btConvexHullShape::getVertex(int i,btVector3& vtx) const
{
- vtx = m_points[i]*m_localScaling;
+ vtx = getScaledPoint(i);
}
int btConvexHullShape::getNumPlanes() const
@@ -171,16 +172,16 @@ int btConvexHullShape::getNumPlanes() const
return 0;
}
-void btConvexHullShape::getPlane(btVector3& ,btPoint3& ,int ) const
+void btConvexHullShape::getPlane(btVector3& ,btVector3& ,int ) const
{
btAssert(0);
}
//not yet
-bool btConvexHullShape::isInside(const btPoint3& ,btScalar ) const
+bool btConvexHullShape::isInside(const btVector3& ,btScalar ) const
{
- assert(0);
+ btAssert(0);
return false;
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h
index 4773de2dc51..baf074be6c3 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h
@@ -24,7 +24,7 @@ subject to the following restrictions:
///Bullet provides a general and fast collision detector for convex shapes based on GJK and EPA using localGetSupportingVertex.
ATTRIBUTE_ALIGNED16(class) btConvexHullShape : public btPolyhedralConvexShape
{
- btAlignedObjectArray<btPoint3> m_points;
+ btAlignedObjectArray<btVector3> m_unscaledPoints;
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
@@ -33,23 +33,38 @@ public:
///this constructor optionally takes in a pointer to points. Each point is assumed to be 3 consecutive btScalar (x,y,z), the striding defines the number of bytes between each point, in memory.
///It is easier to not pass any points in the constructor, and just add one point at a time, using addPoint.
///btConvexHullShape make an internal copy of the points.
- btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(btPoint3));
+ btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(btVector3));
- void addPoint(const btPoint3& point);
+ void addPoint(const btVector3& point);
- btPoint3* getPoints()
+
+ btVector3* getUnscaledPoints()
+ {
+ return &m_unscaledPoints[0];
+ }
+
+ const btVector3* getUnscaledPoints() const
+ {
+ return &m_unscaledPoints[0];
+ }
+
+ ///getPoints is obsolete, please use getUnscaledPoints
+ const btVector3* getPoints() const
{
- return &m_points[0];
+ return getUnscaledPoints();
}
- const btPoint3* getPoints() const
+
+
+
+ SIMD_FORCE_INLINE btVector3 getScaledPoint(int i) const
{
- return &m_points[0];
+ return m_unscaledPoints[i] * m_localScaling;
}
- int getNumPoints() const
+ SIMD_FORCE_INLINE int getNumPoints() const
{
- return m_points.size();
+ return m_unscaledPoints.size();
}
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
@@ -57,7 +72,6 @@ public:
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
- virtual int getShapeType()const { return CONVEX_HULL_SHAPE_PROXYTYPE; }
//debugging
virtual const char* getName()const {return "Convex";}
@@ -65,11 +79,11 @@ public:
virtual int getNumVertices() const;
virtual int getNumEdges() const;
- virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const;
- virtual void getVertex(int i,btPoint3& vtx) const;
+ virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
+ virtual void getVertex(int i,btVector3& vtx) const;
virtual int getNumPlanes() const;
- virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const;
- virtual bool isInside(const btPoint3& pt,btScalar tolerance) const;
+ virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const;
+ virtual bool isInside(const btVector3& pt,btScalar tolerance) const;
///in case we receive negative scaling
virtual void setLocalScaling(const btVector3& scaling);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp
index fb81c8a5bde..bfb741310e1 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp
@@ -17,6 +17,7 @@ subject to the following restrictions:
#include "btConvexInternalShape.h"
+
btConvexInternalShape::btConvexInternalShape()
: m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
m_collisionMargin(CONVEX_DISTANCE_MARGIN)
@@ -48,7 +49,8 @@ void btConvexInternalShape::getAabbSlow(const btTransform& trans,btVector3&minAa
tmp = trans(localGetSupportingVertex(vec*trans.getBasis()));
minAabb[i] = tmp[i]-margin;
}
-};
+}
+
btVector3 btConvexInternalShape::localGetSupportingVertex(const btVector3& vec)const
@@ -70,6 +72,7 @@ btVector3 btConvexInternalShape::localGetSupportingVertex(const btVector3& vec)c
return supVertex;
#else
+ btAssert(0);
return btVector3(0,0,0);
#endif //__SPU__
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h
index 9388ccf31f2..bab720d7b6d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h
@@ -19,23 +19,18 @@ class btConvexInternalShape : public btConvexShape
btScalar m_padding;
+ btConvexInternalShape();
+
public:
- btConvexInternalShape();
+
virtual ~btConvexInternalShape()
{
}
-
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
-#ifndef __SPU__
- virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0;
-
- //notice that the vectors should be unit length
- virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0;
-#endif //#ifndef __SPU__
const btVector3& getImplicitShapeDimensions() const
{
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
new file mode 100644
index 00000000000..4ab5d692945
--- /dev/null
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
@@ -0,0 +1,156 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+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 "btConvexPointCloudShape.h"
+#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
+
+#include "LinearMath/btQuaternion.h"
+
+void btConvexPointCloudShape::setLocalScaling(const btVector3& scaling)
+{
+ m_localScaling = scaling;
+ recalcLocalAabb();
+}
+
+#ifndef __SPU__
+btVector3 btConvexPointCloudShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
+{
+ btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
+ btScalar newDot,maxDot = btScalar(-1e30);
+
+ btVector3 vec = vec0;
+ btScalar lenSqr = vec.length2();
+ if (lenSqr < btScalar(0.0001))
+ {
+ vec.setValue(1,0,0);
+ } else
+ {
+ btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
+ vec *= rlen;
+ }
+
+
+ for (int i=0;i<m_numPoints;i++)
+ {
+ btVector3 vtx = getScaledPoint(i);
+
+ newDot = vec.dot(vtx);
+ if (newDot > maxDot)
+ {
+ maxDot = newDot;
+ supVec = vtx;
+ }
+ }
+ return supVec;
+}
+
+void btConvexPointCloudShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+ btScalar newDot;
+ //use 'w' component of supportVerticesOut?
+ {
+ for (int i=0;i<numVectors;i++)
+ {
+ supportVerticesOut[i][3] = btScalar(-1e30);
+ }
+ }
+ for (int i=0;i<m_numPoints;i++)
+ {
+ btVector3 vtx = getScaledPoint(i);
+
+ for (int j=0;j<numVectors;j++)
+ {
+ const btVector3& vec = vectors[j];
+
+ newDot = vec.dot(vtx);
+ if (newDot > supportVerticesOut[j][3])
+ {
+ //WARNING: don't swap next lines, the w component would get overwritten!
+ supportVerticesOut[j] = vtx;
+ supportVerticesOut[j][3] = newDot;
+ }
+ }
+ }
+
+
+
+}
+
+
+
+btVector3 btConvexPointCloudShape::localGetSupportingVertex(const btVector3& vec)const
+{
+ btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
+
+ if ( getMargin()!=btScalar(0.) )
+ {
+ btVector3 vecnorm = vec;
+ if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
+ {
+ vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
+ }
+ vecnorm.normalize();
+ supVertex+= getMargin() * vecnorm;
+ }
+ return supVertex;
+}
+
+
+#endif
+
+
+
+
+
+
+//currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection
+//Please note that you can debug-draw btConvexHullShape with the Raytracer Demo
+int btConvexPointCloudShape::getNumVertices() const
+{
+ return m_numPoints;
+}
+
+int btConvexPointCloudShape::getNumEdges() const
+{
+ return 0;
+}
+
+void btConvexPointCloudShape::getEdge(int i,btVector3& pa,btVector3& pb) const
+{
+ btAssert (0);
+}
+
+void btConvexPointCloudShape::getVertex(int i,btVector3& vtx) const
+{
+ vtx = m_unscaledPoints[i]*m_localScaling;
+}
+
+int btConvexPointCloudShape::getNumPlanes() const
+{
+ return 0;
+}
+
+void btConvexPointCloudShape::getPlane(btVector3& ,btVector3& ,int ) const
+{
+
+ btAssert(0);
+}
+
+//not yet
+bool btConvexPointCloudShape::isInside(const btVector3& ,btScalar ) const
+{
+ btAssert(0);
+ return false;
+}
+
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h
new file mode 100644
index 00000000000..7e1c13b29c1
--- /dev/null
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h
@@ -0,0 +1,96 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+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_CONVEX_POINT_CLOUD_SHAPE_H
+#define BT_CONVEX_POINT_CLOUD_SHAPE_H
+
+#include "btPolyhedralConvexShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#include "LinearMath/btAlignedObjectArray.h"
+
+///The btConvexPointCloudShape implements an implicit convex hull of an array of vertices.
+ATTRIBUTE_ALIGNED16(class) btConvexPointCloudShape : public btPolyhedralConvexShape
+{
+ btVector3* m_unscaledPoints;
+ int m_numPoints;
+
+public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
+ btConvexPointCloudShape(btVector3* points,int numPoints, const btVector3& localScaling,bool computeAabb = true)
+ {
+ m_localScaling = localScaling;
+ m_shapeType = CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE;
+ m_unscaledPoints = points;
+ m_numPoints = numPoints;
+
+ if (computeAabb)
+ recalcLocalAabb();
+ }
+
+ void setPoints (btVector3* points, int numPoints, bool computeAabb = true)
+ {
+ m_unscaledPoints = points;
+ m_numPoints = numPoints;
+
+ if (computeAabb)
+ recalcLocalAabb();
+ }
+
+ SIMD_FORCE_INLINE btVector3* getUnscaledPoints()
+ {
+ return m_unscaledPoints;
+ }
+
+ SIMD_FORCE_INLINE const btVector3* getUnscaledPoints() const
+ {
+ return m_unscaledPoints;
+ }
+
+ SIMD_FORCE_INLINE int getNumPoints() const
+ {
+ return m_numPoints;
+ }
+
+ SIMD_FORCE_INLINE btVector3 getScaledPoint( int index) const
+ {
+ return m_unscaledPoints[index] * m_localScaling;
+ }
+
+#ifndef __SPU__
+ virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
+ virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
+ virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+#endif
+
+
+ //debugging
+ virtual const char* getName()const {return "ConvexPointCloud";}
+
+ virtual int getNumVertices() const;
+ virtual int getNumEdges() const;
+ virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
+ virtual void getVertex(int i,btVector3& vtx) const;
+ virtual int getNumPlanes() const;
+ virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const;
+ virtual bool isInside(const btVector3& pt,btScalar tolerance) const;
+
+ ///in case we receive negative scaling
+ virtual void setLocalScaling(const btVector3& scaling);
+};
+
+
+#endif //BT_CONVEX_POINT_CLOUD_SHAPE_H
+
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp
index 7afcccf8b03..7e67696f4c7 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp
@@ -14,5 +14,366 @@ subject to the following restrictions:
*/
#include "btConvexShape.h"
+#include "btTriangleShape.h"
+#include "btSphereShape.h"
+#include "btCylinderShape.h"
+#include "btCapsuleShape.h"
+#include "btConvexHullShape.h"
+#include "btConvexPointCloudShape.h"
+btConvexShape::btConvexShape ()
+{
+}
+btConvexShape::~btConvexShape()
+{
+
+}
+
+
+
+static btVector3 convexHullSupport (const btVector3& localDir, const btVector3* points, int numPoints, const btVector3& localScaling)
+{
+ btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
+ btScalar newDot,maxDot = btScalar(-1e30);
+
+ btVector3 vec0(localDir.getX(),localDir.getY(),localDir.getZ());
+ btVector3 vec = vec0;
+ btScalar lenSqr = vec.length2();
+ if (lenSqr < btScalar(0.0001))
+ {
+ vec.setValue(1,0,0);
+ } else {
+ btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
+ vec *= rlen;
+ }
+
+
+ for (int i=0;i<numPoints;i++)
+ {
+ btVector3 vtx = points[i] * localScaling;
+
+ newDot = vec.dot(vtx);
+ if (newDot > maxDot)
+ {
+ maxDot = newDot;
+ supVec = vtx;
+ }
+ }
+ return btVector3(supVec.getX(),supVec.getY(),supVec.getZ());
+}
+
+btVector3 btConvexShape::localGetSupportVertexWithoutMarginNonVirtual (const btVector3& localDir) const
+{
+ switch (m_shapeType)
+ {
+ case SPHERE_SHAPE_PROXYTYPE:
+ {
+ return btVector3(0,0,0);
+ }
+ case BOX_SHAPE_PROXYTYPE:
+ {
+ btBoxShape* convexShape = (btBoxShape*)this;
+ const btVector3& halfExtents = convexShape->getImplicitShapeDimensions();
+
+ return btVector3(btFsels(localDir.x(), halfExtents.x(), -halfExtents.x()),
+ btFsels(localDir.y(), halfExtents.y(), -halfExtents.y()),
+ btFsels(localDir.z(), halfExtents.z(), -halfExtents.z()));
+ }
+ case TRIANGLE_SHAPE_PROXYTYPE:
+ {
+ btTriangleShape* triangleShape = (btTriangleShape*)this;
+ btVector3 dir(localDir.getX(),localDir.getY(),localDir.getZ());
+ btVector3* vertices = &triangleShape->m_vertices1[0];
+ btVector3 dots(dir.dot(vertices[0]), dir.dot(vertices[1]), dir.dot(vertices[2]));
+ btVector3 sup = vertices[dots.maxAxis()];
+ return btVector3(sup.getX(),sup.getY(),sup.getZ());
+ }
+ case CYLINDER_SHAPE_PROXYTYPE:
+ {
+ btCylinderShape* cylShape = (btCylinderShape*)this;
+ //mapping of halfextents/dimension onto radius/height depends on how cylinder local orientation is (upAxis)
+
+ btVector3 halfExtents = cylShape->getImplicitShapeDimensions();
+ btVector3 v(localDir.getX(),localDir.getY(),localDir.getZ());
+ int cylinderUpAxis = cylShape->getUpAxis();
+ int XX(1),YY(0),ZZ(2);
+
+ switch (cylinderUpAxis)
+ {
+ case 0:
+ {
+ XX = 1;
+ YY = 0;
+ ZZ = 2;
+ }
+ break;
+ case 1:
+ {
+ XX = 0;
+ YY = 1;
+ ZZ = 2;
+ }
+ break;
+ case 2:
+ {
+ XX = 0;
+ YY = 2;
+ ZZ = 1;
+
+ }
+ break;
+ default:
+ btAssert(0);
+ break;
+ };
+
+ btScalar radius = halfExtents[XX];
+ btScalar halfHeight = halfExtents[cylinderUpAxis];
+
+ btVector3 tmp;
+ btScalar d ;
+
+ btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
+ if (s != btScalar(0.0))
+ {
+ d = radius / s;
+ tmp[XX] = v[XX] * d;
+ tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+ tmp[ZZ] = v[ZZ] * d;
+ return btVector3(tmp.getX(),tmp.getY(),tmp.getZ());
+ } else {
+ tmp[XX] = radius;
+ tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+ tmp[ZZ] = btScalar(0.0);
+ return btVector3(tmp.getX(),tmp.getY(),tmp.getZ());
+ }
+ }
+ case CAPSULE_SHAPE_PROXYTYPE:
+ {
+ btVector3 vec0(localDir.getX(),localDir.getY(),localDir.getZ());
+
+ btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
+ btScalar halfHeight = capsuleShape->getHalfHeight();
+ int capsuleUpAxis = capsuleShape->getUpAxis();
+
+ btScalar radius = capsuleShape->getRadius();
+ btVector3 supVec(0,0,0);
+
+ btScalar maxDot(btScalar(-1e30));
+
+ btVector3 vec = vec0;
+ btScalar lenSqr = vec.length2();
+ if (lenSqr < btScalar(0.0001))
+ {
+ vec.setValue(1,0,0);
+ } else
+ {
+ btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
+ vec *= rlen;
+ }
+ btVector3 vtx;
+ btScalar newDot;
+ {
+ btVector3 pos(0,0,0);
+ pos[capsuleUpAxis] = halfHeight;
+
+ //vtx = pos +vec*(radius);
+ vtx = pos +vec*capsuleShape->getLocalScalingNV()*(radius) - vec * capsuleShape->getMarginNV();
+ newDot = vec.dot(vtx);
+
+
+ if (newDot > maxDot)
+ {
+ maxDot = newDot;
+ supVec = vtx;
+ }
+ }
+ {
+ btVector3 pos(0,0,0);
+ pos[capsuleUpAxis] = -halfHeight;
+
+ //vtx = pos +vec*(radius);
+ vtx = pos +vec*capsuleShape->getLocalScalingNV()*(radius) - vec * capsuleShape->getMarginNV();
+ newDot = vec.dot(vtx);
+ if (newDot > maxDot)
+ {
+ maxDot = newDot;
+ supVec = vtx;
+ }
+ }
+ return btVector3(supVec.getX(),supVec.getY(),supVec.getZ());
+ }
+ case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
+ {
+ btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this;
+ btVector3* points = convexPointCloudShape->getUnscaledPoints ();
+ int numPoints = convexPointCloudShape->getNumPoints ();
+ return convexHullSupport (localDir, points, numPoints,convexPointCloudShape->getLocalScalingNV());
+ }
+ case CONVEX_HULL_SHAPE_PROXYTYPE:
+ {
+ btConvexHullShape* convexHullShape = (btConvexHullShape*)this;
+ btVector3* points = convexHullShape->getUnscaledPoints();
+ int numPoints = convexHullShape->getNumPoints ();
+ return convexHullSupport (localDir, points, numPoints,convexHullShape->getLocalScalingNV());
+ }
+ default:
+#ifndef __SPU__
+ return this->localGetSupportingVertexWithoutMargin (localDir);
+#else
+ btAssert (0);
+#endif
+ }
+
+ // should never reach here
+ btAssert (0);
+ return btVector3 (btScalar(0.0f), btScalar(0.0f), btScalar(0.0f));
+}
+
+btVector3 btConvexShape::localGetSupportVertexNonVirtual (const btVector3& localDir) const
+{
+ btVector3 localDirNorm = localDir;
+ if (localDirNorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
+ {
+ localDirNorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
+ }
+ localDirNorm.normalize ();
+
+ return localGetSupportVertexWithoutMarginNonVirtual(localDirNorm)+ getMarginNonVirtual() * localDirNorm;
+}
+
+/* TODO: This should be bumped up to btCollisionShape () */
+btScalar btConvexShape::getMarginNonVirtual () const
+{
+ switch (m_shapeType)
+ {
+ case SPHERE_SHAPE_PROXYTYPE:
+ {
+ btSphereShape* sphereShape = (btSphereShape*)this;
+ return sphereShape->getRadius ();
+ }
+ case BOX_SHAPE_PROXYTYPE:
+ {
+ btBoxShape* convexShape = (btBoxShape*)this;
+ return convexShape->getMarginNV ();
+ }
+ case TRIANGLE_SHAPE_PROXYTYPE:
+ {
+ btTriangleShape* triangleShape = (btTriangleShape*)this;
+ return triangleShape->getMarginNV ();
+ }
+ case CYLINDER_SHAPE_PROXYTYPE:
+ {
+ btCylinderShape* cylShape = (btCylinderShape*)this;
+ return cylShape->getMarginNV();
+ }
+ case CAPSULE_SHAPE_PROXYTYPE:
+ {
+ btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
+ return capsuleShape->getMarginNV();
+ }
+ case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
+ /* fall through */
+ case CONVEX_HULL_SHAPE_PROXYTYPE:
+ {
+ btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this;
+ return convexHullShape->getMarginNV();
+ }
+ default:
+#ifndef __SPU__
+ return this->getMargin ();
+#else
+ btAssert (0);
+#endif
+ }
+
+ // should never reach here
+ btAssert (0);
+ return btScalar(0.0f);
+}
+
+void btConvexShape::getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
+{
+ switch (m_shapeType)
+ {
+ case SPHERE_SHAPE_PROXYTYPE:
+ {
+ btSphereShape* sphereShape = (btSphereShape*)this;
+ btScalar radius = sphereShape->getImplicitShapeDimensions().getX();// * convexShape->getLocalScaling().getX();
+ btScalar margin = radius + sphereShape->getMarginNonVirtual();
+ const btVector3& center = t.getOrigin();
+ btVector3 extent(margin,margin,margin);
+ aabbMin = center - extent;
+ aabbMax = center + extent;
+ }
+ break;
+ case CYLINDER_SHAPE_PROXYTYPE:
+ /* fall through */
+ case BOX_SHAPE_PROXYTYPE:
+ {
+ btBoxShape* convexShape = (btBoxShape*)this;
+ btScalar margin=convexShape->getMarginNonVirtual();
+ btVector3 halfExtents = convexShape->getImplicitShapeDimensions();
+ halfExtents += btVector3(margin,margin,margin);
+ btMatrix3x3 abs_b = t.getBasis().absolute();
+ btVector3 center = t.getOrigin();
+ btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
+
+ aabbMin = center - extent;
+ aabbMax = center + extent;
+ break;
+ }
+ case TRIANGLE_SHAPE_PROXYTYPE:
+ {
+ btTriangleShape* triangleShape = (btTriangleShape*)this;
+ btScalar margin = triangleShape->getMarginNonVirtual();
+ for (int i=0;i<3;i++)
+ {
+ btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
+ vec[i] = btScalar(1.);
+
+ btVector3 sv = localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis());
+
+ btVector3 tmp = t(sv);
+ aabbMax[i] = tmp[i]+margin;
+ vec[i] = btScalar(-1.);
+ tmp = t(localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis()));
+ aabbMin[i] = tmp[i]-margin;
+ }
+ }
+ break;
+ case CAPSULE_SHAPE_PROXYTYPE:
+ {
+ btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
+ btVector3 halfExtents(capsuleShape->getRadius(),capsuleShape->getRadius(),capsuleShape->getRadius());
+ int m_upAxis = capsuleShape->getUpAxis();
+ halfExtents[m_upAxis] = capsuleShape->getRadius() + capsuleShape->getHalfHeight();
+ halfExtents += btVector3(capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual());
+ btMatrix3x3 abs_b = t.getBasis().absolute();
+ btVector3 center = t.getOrigin();
+ btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
+ aabbMin = center - extent;
+ aabbMax = center + extent;
+ }
+ break;
+ case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
+ case CONVEX_HULL_SHAPE_PROXYTYPE:
+ {
+ btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this;
+ btScalar margin = convexHullShape->getMarginNonVirtual();
+ convexHullShape->getNonvirtualAabb (t, aabbMin, aabbMax, margin);
+ }
+ break;
+ default:
+#ifndef __SPU__
+ this->getAabb (t, aabbMin, aabbMax);
+#else
+ btAssert (0);
+#endif
+ break;
+ }
+
+ // should never reach here
+ btAssert (0);
+}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h
index e4eb7f6dbf6..0cc7b349521 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.h
@@ -24,8 +24,6 @@ subject to the following restrictions:
#include "btCollisionMargin.h"
#include "LinearMath/btAlignedAllocator.h"
-//todo: get rid of this btConvexCastResult thing!
-struct btConvexCastResult;
#define MAX_PREFERRED_PENETRATION_DIRECTIONS 10
/// The btConvexShape is an abstract shape interface, implemented by all convex shapes such as btBoxShape, btConvexHullShape etc.
@@ -38,20 +36,25 @@ public:
BT_DECLARE_ALIGNED_ALLOCATOR();
- virtual ~btConvexShape()
- {
+ btConvexShape ();
- }
+ virtual ~btConvexShape();
+ virtual btVector3 localGetSupportingVertex(const btVector3& vec)const = 0;
+
+ ////////
+ #ifndef __SPU__
+ virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const=0;
+ #endif //#ifndef __SPU__
+
+ btVector3 localGetSupportVertexWithoutMarginNonVirtual (const btVector3& vec) const;
+ btVector3 localGetSupportVertexNonVirtual (const btVector3& vec) const;
+ btScalar getMarginNonVirtual () const;
+ void getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const;
- virtual btVector3 localGetSupportingVertex(const btVector3& vec)const =0;
-#ifndef __SPU__
- virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0;
//notice that the vectors should be unit length
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0;
-#endif //#ifndef __SPU__
-
///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0;
@@ -69,6 +72,9 @@ public:
virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const=0;
+
+
+
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp
index 02a293e82ba..4bd986bb7f7 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp
@@ -20,8 +20,9 @@ subject to the following restrictions:
btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface, bool calcAabb)
-:m_stridingMesh(meshInterface)
+: btPolyhedralConvexShape(), m_stridingMesh(meshInterface)
{
+ m_shapeType = CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE;
if ( calcAabb )
recalcLocalAabb();
}
@@ -107,7 +108,7 @@ void btConvexTriangleMeshShape::batchedUnitVectorGetSupportingVertexWithoutMargi
}
}
- //todo: could do the batch inside the callback!
+ ///@todo: could do the batch inside the callback!
for (int j=0;j<numVectors;j++)
@@ -162,12 +163,12 @@ int btConvexTriangleMeshShape::getNumEdges() const
return 0;
}
-void btConvexTriangleMeshShape::getEdge(int ,btPoint3& ,btPoint3& ) const
+void btConvexTriangleMeshShape::getEdge(int ,btVector3& ,btVector3& ) const
{
btAssert(0);
}
-void btConvexTriangleMeshShape::getVertex(int ,btPoint3& ) const
+void btConvexTriangleMeshShape::getVertex(int ,btVector3& ) const
{
btAssert(0);
}
@@ -177,13 +178,13 @@ int btConvexTriangleMeshShape::getNumPlanes() const
return 0;
}
-void btConvexTriangleMeshShape::getPlane(btVector3& ,btPoint3& ,int ) const
+void btConvexTriangleMeshShape::getPlane(btVector3& ,btVector3& ,int ) const
{
btAssert(0);
}
//not yet
-bool btConvexTriangleMeshShape::isInside(const btPoint3& ,btScalar ) const
+bool btConvexTriangleMeshShape::isInside(const btVector3& ,btScalar ) const
{
btAssert(0);
return false;
@@ -268,15 +269,12 @@ void btConvexTriangleMeshShape::calculatePrincipalAxisTransform(btTransform& pri
btVector3 a = triangle[0] - center;
btVector3 b = triangle[1] - center;
btVector3 c = triangle[2] - center;
- btVector3 abc = a + b + c;
btScalar volNeg = -btFabs(a.triple(b, c)) * btScalar(1. / 6);
for (int j = 0; j < 3; j++)
{
for (int k = 0; k <= j; k++)
{
- i[j][k] = i[k][j] = volNeg * (center[j] * center[k]
- + btScalar(0.25) * (center[j] * abc[k] + center[k] * abc[j])
- + btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k])
+ i[j][k] = i[k][j] = volNeg * (btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k])
+ btScalar(0.05) * (a[j] * b[k] + a[k] * b[j] + a[j] * c[k] + a[k] * c[j] + b[j] * c[k] + b[k] * c[j]));
}
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
index 6ff0bf5d43b..9d7e39fce69 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
@@ -29,18 +29,16 @@ public:
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
- virtual int getShapeType()const { return CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE; }
-
//debugging
virtual const char* getName()const {return "ConvexTrimesh";}
virtual int getNumVertices() const;
virtual int getNumEdges() const;
- virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const;
- virtual void getVertex(int i,btPoint3& vtx) const;
+ virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
+ virtual void getVertex(int i,btVector3& vtx) const;
virtual int getNumPlanes() const;
- virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const;
- virtual bool isInside(const btPoint3& pt,btScalar tolerance) const;
+ virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const;
+ virtual bool isInside(const btVector3& pt,btScalar tolerance) const;
virtual void setLocalScaling(const btVector3& scaling);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp
index 3afef1c7550..c9fa907edf3 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.cpp
@@ -13,12 +13,12 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
#include "btCylinderShape.h"
-#include "LinearMath/btPoint3.h"
btCylinderShape::btCylinderShape (const btVector3& halfExtents)
:btBoxShape(halfExtents),
m_upAxis(1)
{
+ m_shapeType = CYLINDER_SHAPE_PROXYTYPE;
recalcLocalAabb();
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h
index 30938acf7c7..bda74a8612d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h
@@ -62,11 +62,7 @@ public:
//use box inertia
// virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
- virtual int getShapeType() const
- {
- return CYLINDER_SHAPE_PROXYTYPE;
- }
-
+
int getUpAxis() const
{
return m_upAxis;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.cpp
index 6954aad7917..8387b9584bb 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.cpp
@@ -19,8 +19,9 @@ subject to the following restrictions:
#include "btCollisionShape.h"
-btEmptyShape::btEmptyShape()
+btEmptyShape::btEmptyShape() : btConcaveShape ()
{
+ m_shapeType = EMPTY_SHAPE_PROXYTYPE;
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h
index d7d78407b61..8720d53ae63 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h
@@ -51,14 +51,14 @@ public:
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
- virtual int getShapeType() const { return EMPTY_SHAPE_PROXYTYPE;}
-
-
virtual const char* getName()const
{
return "Empty";
}
+ virtual void processAllTriangles(btTriangleCallback* ,const btVector3& ,const btVector3& ) const
+ {
+ }
protected:
btVector3 m_localScaling;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
index a291d6b7ce7..7d4875d8037 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
@@ -18,71 +18,107 @@ subject to the following restrictions:
#include "LinearMath/btTransformUtil.h"
-btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength,void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges)
-: m_heightStickWidth(heightStickWidth),
-m_heightStickLength(heightStickLength),
-m_maxHeight(maxHeight),
-m_width((btScalar)heightStickWidth-1),
-m_length((btScalar)heightStickLength-1),
-m_heightfieldDataUnknown(heightfieldData),
-m_useFloatData(useFloatData),
-m_flipQuadEdges(flipQuadEdges),
-m_useDiamondSubdivision(false),
-m_upAxis(upAxis),
-m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.))
+
+btHeightfieldTerrainShape::btHeightfieldTerrainShape
+(
+int heightStickWidth, int heightStickLength, void* heightfieldData,
+btScalar heightScale, btScalar minHeight, btScalar maxHeight,int upAxis,
+PHY_ScalarType hdt, bool flipQuadEdges
+)
{
+ initialize(heightStickWidth, heightStickLength, heightfieldData,
+ heightScale, minHeight, maxHeight, upAxis, hdt,
+ flipQuadEdges);
+}
+
- btScalar quantizationMargin = 1.f;
+btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength,void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges)
+{
+ // legacy constructor: support only float or unsigned char,
+ // and min height is zero
+ PHY_ScalarType hdt = (useFloatData) ? PHY_FLOAT : PHY_UCHAR;
+ btScalar minHeight = 0.0;
+
+ // previously, height = uchar * maxHeight / 65535.
+ // So to preserve legacy behavior, heightScale = maxHeight / 65535
+ btScalar heightScale = maxHeight / 65535;
+
+ initialize(heightStickWidth, heightStickLength, heightfieldData,
+ heightScale, minHeight, maxHeight, upAxis, hdt,
+ flipQuadEdges);
+}
- //enlarge the AABB to avoid division by zero when initializing the quantization values
- btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin);
- btVector3 halfExtents(0,0,0);
+void btHeightfieldTerrainShape::initialize
+(
+int heightStickWidth, int heightStickLength, void* heightfieldData,
+btScalar heightScale, btScalar minHeight, btScalar maxHeight, int upAxis,
+PHY_ScalarType hdt, bool flipQuadEdges
+)
+{
+ // validation
+ btAssert(heightStickWidth > 1 && "bad width");
+ btAssert(heightStickLength > 1 && "bad length");
+ btAssert(heightfieldData && "null heightfield data");
+ // btAssert(heightScale) -- do we care? Trust caller here
+ btAssert(minHeight <= maxHeight && "bad min/max height");
+ btAssert(upAxis >= 0 && upAxis < 3 &&
+ "bad upAxis--should be in range [0,2]");
+ btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT &&
+ "Bad height data type enum");
+
+ // initialize member variables
+ m_shapeType = TERRAIN_SHAPE_PROXYTYPE;
+ m_heightStickWidth = heightStickWidth;
+ m_heightStickLength = heightStickLength;
+ m_minHeight = minHeight;
+ m_maxHeight = maxHeight;
+ m_width = (btScalar) (heightStickWidth - 1);
+ m_length = (btScalar) (heightStickLength - 1);
+ m_heightScale = heightScale;
+ m_heightfieldDataUnknown = heightfieldData;
+ m_heightDataType = hdt;
+ m_flipQuadEdges = flipQuadEdges;
+ m_useDiamondSubdivision = false;
+ m_upAxis = upAxis;
+ m_localScaling.setValue(btScalar(1.), btScalar(1.), btScalar(1.));
+
+ // determine min/max axis-aligned bounding box (aabb) values
switch (m_upAxis)
{
case 0:
{
- halfExtents.setValue(
- btScalar(m_maxHeight),
- btScalar(m_width), //?? don't know if this should change
- btScalar(m_length));
+ m_localAabbMin.setValue(m_minHeight, 0, 0);
+ m_localAabbMax.setValue(m_maxHeight, m_width, m_length);
break;
}
case 1:
{
- halfExtents.setValue(
- btScalar(m_width),
- btScalar(m_maxHeight),
- btScalar(m_length));
+ m_localAabbMin.setValue(0, m_minHeight, 0);
+ m_localAabbMax.setValue(m_width, m_maxHeight, m_length);
break;
};
case 2:
{
- halfExtents.setValue(
- btScalar(m_width),
- btScalar(m_length),
- btScalar(m_maxHeight)
- );
+ m_localAabbMin.setValue(0, 0, m_minHeight);
+ m_localAabbMax.setValue(m_width, m_length, m_maxHeight);
break;
}
default:
{
//need to get valid m_upAxis
- btAssert(0);
+ btAssert(0 && "Bad m_upAxis");
}
}
- halfExtents*= btScalar(0.5);
-
- m_localAabbMin = -halfExtents - clampValue;
- m_localAabbMax = halfExtents + clampValue;
- btVector3 aabbSize = m_localAabbMax - m_localAabbMin;
-
+ // remember origin (defined as exact middle of aabb)
+ m_localOrigin = btScalar(0.5) * (m_localAabbMin + m_localAabbMax);
}
+
btHeightfieldTerrainShape::~btHeightfieldTerrainShape()
{
}
@@ -92,57 +128,80 @@ btHeightfieldTerrainShape::~btHeightfieldTerrainShape()
void btHeightfieldTerrainShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
{
btVector3 halfExtents = (m_localAabbMax-m_localAabbMin)* m_localScaling * btScalar(0.5);
- halfExtents += btVector3(getMargin(),getMargin(),getMargin());
+
+ btVector3 localOrigin(0, 0, 0);
+ localOrigin[m_upAxis] = (m_minHeight + m_maxHeight) * btScalar(0.5);
+ localOrigin *= m_localScaling;
btMatrix3x3 abs_b = t.getBasis().absolute();
- btPoint3 center = t.getOrigin();
+ btVector3 center = t.getOrigin();
btVector3 extent = btVector3(abs_b[0].dot(halfExtents),
abs_b[1].dot(halfExtents),
abs_b[2].dot(halfExtents));
-
+ extent += btVector3(getMargin(),getMargin(),getMargin());
aabbMin = center - extent;
aabbMax = center + extent;
-
-
}
-btScalar btHeightfieldTerrainShape::getHeightFieldValue(int x,int y) const
+
+/// This returns the "raw" (user's initial) height, not the actual height.
+/// The actual height needs to be adjusted to be relative to the center
+/// of the heightfield's AABB.
+btScalar
+btHeightfieldTerrainShape::getRawHeightFieldValue(int x,int y) const
{
btScalar val = 0.f;
- if (m_useFloatData)
+ switch (m_heightDataType)
{
- val = m_heightfieldDataFloat[(y*m_heightStickWidth)+x];
- } else
- {
- //assume unsigned short int
- unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_heightStickWidth)+x];
- val = heightFieldValue* (m_maxHeight/btScalar(65535));
+ case PHY_FLOAT:
+ {
+ val = m_heightfieldDataFloat[(y*m_heightStickWidth)+x];
+ break;
+ }
+
+ case PHY_UCHAR:
+ {
+ unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_heightStickWidth)+x];
+ val = heightFieldValue * m_heightScale;
+ break;
+ }
+
+ case PHY_SHORT:
+ {
+ short hfValue = m_heightfieldDataShort[(y * m_heightStickWidth) + x];
+ val = hfValue * m_heightScale;
+ break;
+ }
+
+ default:
+ {
+ btAssert(!"Bad m_heightDataType");
+ }
}
+
return val;
}
-
+/// this returns the vertex in bullet-local coordinates
void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const
{
-
btAssert(x>=0);
btAssert(y>=0);
btAssert(x<m_heightStickWidth);
btAssert(y<m_heightStickLength);
-
- btScalar height = getHeightFieldValue(x,y);
+ btScalar height = getRawHeightFieldValue(x,y);
switch (m_upAxis)
{
case 0:
{
vertex.setValue(
- height,
+ height - m_localOrigin.getX(),
(-m_width/btScalar(2.0)) + x,
(-m_length/btScalar(2.0) ) + y
);
@@ -152,7 +211,7 @@ void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const
{
vertex.setValue(
(-m_width/btScalar(2.0)) + x,
- height,
+ height - m_localOrigin.getY(),
(-m_length/btScalar(2.0)) + y
);
break;
@@ -162,7 +221,7 @@ void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const
vertex.setValue(
(-m_width/btScalar(2.0)) + x,
(-m_length/btScalar(2.0)) + y,
- height
+ height - m_localOrigin.getZ()
);
break;
}
@@ -174,45 +233,76 @@ void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const
}
vertex*=m_localScaling;
-
}
+
+static inline int
+getQuantized
+(
+btScalar x
+)
+{
+ if (x < 0.0) {
+ return (int) (x - 0.5);
+ }
+ return (int) (x + 0.5);
+}
+
+
+
+/// given input vector, return quantized version
+/**
+ This routine is basically determining the gridpoint indices for a given
+ input vector, answering the question: "which gridpoint is closest to the
+ provided point?".
+
+ "with clamp" means that we restrict the point to be in the heightfield's
+ axis-aligned bounding box.
+ */
void btHeightfieldTerrainShape::quantizeWithClamp(int* out, const btVector3& point,int /*isMax*/) const
{
btVector3 clampedPoint(point);
clampedPoint.setMax(m_localAabbMin);
clampedPoint.setMin(m_localAabbMax);
- btVector3 v = (clampedPoint);// - m_bvhAabbMin) * m_bvhQuantization;
-
- //TODO: optimization: check out how to removed this btFabs
+ out[0] = getQuantized(clampedPoint.getX());
+ out[1] = getQuantized(clampedPoint.getY());
+ out[2] = getQuantized(clampedPoint.getZ());
- out[0] = (int)(v.getX() + v.getX() / btFabs(v.getX())* btScalar(0.5) );
- out[1] = (int)(v.getY() + v.getY() / btFabs(v.getY())* btScalar(0.5) );
- out[2] = (int)(v.getZ() + v.getZ() / btFabs(v.getZ())* btScalar(0.5) );
-
}
+
+/// process all triangles within the provided axis-aligned bounding box
+/**
+ basic algorithm:
+ - convert input aabb to local coordinates (scale down and shift for local origin)
+ - convert input aabb to a range of heightfield grid points (quantize)
+ - iterate over all triangles in that subset of the grid
+ */
void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
{
- (void)callback;
- (void)aabbMax;
- (void)aabbMin;
+ // scale down the input aabb's so they are in local (non-scaled) coordinates
+ btVector3 localAabbMin = aabbMin*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
+ btVector3 localAabbMax = aabbMax*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
- //quantize the aabbMin and aabbMax, and adjust the start/end ranges
+ // account for local origin
+ localAabbMin += m_localOrigin;
+ localAabbMax += m_localOrigin;
+ //quantize the aabbMin and aabbMax, and adjust the start/end ranges
int quantizedAabbMin[3];
int quantizedAabbMax[3];
-
- btVector3 localAabbMin = aabbMin*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
- btVector3 localAabbMax = aabbMax*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
-
quantizeWithClamp(quantizedAabbMin, localAabbMin,0);
quantizeWithClamp(quantizedAabbMax, localAabbMax,1);
-
+ // expand the min/max quantized values
+ // this is to catch the case where the input aabb falls between grid points!
+ for (int i = 0; i < 3; ++i) {
+ quantizedAabbMin[i]--;
+ quantizedAabbMax[i]++;
+ }
int startX=0;
int endX=m_heightStickWidth-1;
@@ -223,11 +313,6 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
{
case 0:
{
- quantizedAabbMin[1]+=m_heightStickWidth/2-1;
- quantizedAabbMax[1]+=m_heightStickWidth/2+1;
- quantizedAabbMin[2]+=m_heightStickLength/2-1;
- quantizedAabbMax[2]+=m_heightStickLength/2+1;
-
if (quantizedAabbMin[1]>startX)
startX = quantizedAabbMin[1];
if (quantizedAabbMax[1]<endX)
@@ -240,11 +325,6 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
}
case 1:
{
- quantizedAabbMin[0]+=m_heightStickWidth/2-1;
- quantizedAabbMax[0]+=m_heightStickWidth/2+1;
- quantizedAabbMin[2]+=m_heightStickLength/2-1;
- quantizedAabbMax[2]+=m_heightStickLength/2+1;
-
if (quantizedAabbMin[0]>startX)
startX = quantizedAabbMin[0];
if (quantizedAabbMax[0]<endX)
@@ -257,11 +337,6 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
};
case 2:
{
- quantizedAabbMin[0]+=m_heightStickWidth/2-1;
- quantizedAabbMax[0]+=m_heightStickWidth/2+1;
- quantizedAabbMin[1]+=m_heightStickLength/2-1;
- quantizedAabbMax[1]+=m_heightStickLength/2+1;
-
if (quantizedAabbMin[0]>startX)
startX = quantizedAabbMin[0];
if (quantizedAabbMax[0]<endX)
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
index d6890fe6b97..36489a0ebc3 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
@@ -18,28 +18,80 @@ subject to the following restrictions:
#include "btConcaveShape.h"
-///The btHeightfieldTerrainShape simulates a 2D heightfield terrain collision shape. You can also use the more general btBvhTriangleMeshShape instead.
-///An example implementation of btHeightfieldTerrainShape is provided in Demos/VehicleDemo/VehicleDemo.cpp
+///btHeightfieldTerrainShape simulates a 2D heightfield terrain
+/**
+ The caller is responsible for maintaining the heightfield array; this
+ class does not make a copy.
+
+ The heightfield can be dynamic so long as the min/max height values
+ capture the extremes (heights must always be in that range).
+
+ The local origin of the heightfield is assumed to be the exact
+ center (as determined by width and length and height, with each
+ axis multiplied by the localScaling).
+
+ \b NOTE: be careful with coordinates. If you have a heightfield with a local
+ min height of -100m, and a max height of +500m, you may be tempted to place it
+ at the origin (0,0) and expect the heights in world coordinates to be
+ -100 to +500 meters.
+ Actually, the heights will be -300 to +300m, because bullet will re-center
+ the heightfield based on its AABB (which is determined by the min/max
+ heights). So keep in mind that once you create a btHeightfieldTerrainShape
+ object, the heights will be adjusted relative to the center of the AABB. This
+ is different to the behavior of many rendering engines, but is useful for
+ physics engines.
+
+ Most (but not all) rendering and heightfield libraries assume upAxis = 1
+ (that is, the y-axis is "up"). This class allows any of the 3 coordinates
+ to be "up". Make sure your choice of axis is consistent with your rendering
+ system.
+
+ The heightfield heights are determined from the data type used for the
+ heightfieldData array.
+
+ - PHY_UCHAR: height at a point is the uchar value at the
+ grid point, multipled by heightScale. uchar isn't recommended
+ because of its inability to deal with negative values, and
+ low resolution (8-bit).
+
+ - PHY_SHORT: height at a point is the short int value at that grid
+ point, multipled by heightScale.
+
+ - PHY_FLOAT: height at a point is the float value at that grid
+ point. heightScale is ignored when using the float heightfield
+ data type.
+
+ Whatever the caller specifies as minHeight and maxHeight will be honored.
+ The class will not inspect the heightfield to discover the actual minimum
+ or maximum heights. These values are used to determine the heightfield's
+ axis-aligned bounding box, multiplied by localScaling.
+
+ For usage and testing see the TerrainDemo.
+ */
class btHeightfieldTerrainShape : public btConcaveShape
{
protected:
btVector3 m_localAabbMin;
btVector3 m_localAabbMax;
-
+ btVector3 m_localOrigin;
+
///terrain data
int m_heightStickWidth;
int m_heightStickLength;
+ btScalar m_minHeight;
btScalar m_maxHeight;
btScalar m_width;
btScalar m_length;
+ btScalar m_heightScale;
union
{
unsigned char* m_heightfieldDataUnsignedChar;
+ short* m_heightfieldDataShort;
btScalar* m_heightfieldDataFloat;
void* m_heightfieldDataUnknown;
};
-
- bool m_useFloatData;
+
+ PHY_ScalarType m_heightDataType;
bool m_flipQuadEdges;
bool m_useDiamondSubdivision;
@@ -47,31 +99,49 @@ protected:
btVector3 m_localScaling;
- virtual btScalar getHeightFieldValue(int x,int y) const;
+ virtual btScalar getRawHeightFieldValue(int x,int y) const;
void quantizeWithClamp(int* out, const btVector3& point,int isMax) const;
void getVertex(int x,int y,btVector3& vertex) const;
- inline bool testQuantizedAabbAgainstQuantizedAabb(int* aabbMin1, int* aabbMax1,const int* aabbMin2,const int* aabbMax2) const
- {
- bool overlap = true;
- overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
- overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
- overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
- return overlap;
- }
+
+
+ /// protected initialization
+ /**
+ Handles the work of constructors so that public constructors can be
+ backwards-compatible without a lot of copy/paste.
+ */
+ void initialize(int heightStickWidth, int heightStickLength,
+ void* heightfieldData, btScalar heightScale,
+ btScalar minHeight, btScalar maxHeight, int upAxis,
+ PHY_ScalarType heightDataType, bool flipQuadEdges);
public:
- btHeightfieldTerrainShape(int heightStickWidth,int heightStickHeight,void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges);
+ /// preferred constructor
+ /**
+ This constructor supports a range of heightfield
+ data types, and allows for a non-zero minimum height value.
+ heightScale is needed for any integer-based heightfield data types.
+ */
+ btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength,
+ void* heightfieldData, btScalar heightScale,
+ btScalar minHeight, btScalar maxHeight,
+ int upAxis, PHY_ScalarType heightDataType,
+ bool flipQuadEdges);
+
+ /// legacy constructor
+ /**
+ The legacy constructor assumes the heightfield has a minimum height
+ of zero. Only unsigned char or floats are supported. For legacy
+ compatibility reasons, heightScale is calculated as maxHeight / 65535
+ (and is only used when useFloatData = false).
+ */
+ btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength,void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges);
virtual ~btHeightfieldTerrainShape();
void setUseDiamondSubdivision(bool useDiamondSubdivision=true) { m_useDiamondSubdivision = useDiamondSubdivision;}
- virtual int getShapeType() const
- {
- return TERRAIN_SHAPE_PROXYTYPE;
- }
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp
index 8f893ac98aa..b107b0bea6e 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp
@@ -17,23 +17,25 @@ subject to the following restrictions:
btMinkowskiSumShape::btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB)
-:m_shapeA(shapeA),
+: btConvexInternalShape (),
+m_shapeA(shapeA),
m_shapeB(shapeB)
{
+ m_shapeType = MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE;
m_transA.setIdentity();
m_transB.setIdentity();
}
btVector3 btMinkowskiSumShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
{
- btVector3 supVertexA = m_transA(m_shapeA->localGetSupportingVertexWithoutMargin(-vec*m_transA.getBasis()));
- btVector3 supVertexB = m_transB(m_shapeB->localGetSupportingVertexWithoutMargin(vec*m_transB.getBasis()));
+ btVector3 supVertexA = m_transA(m_shapeA->localGetSupportingVertexWithoutMargin(vec*m_transA.getBasis()));
+ btVector3 supVertexB = m_transB(m_shapeB->localGetSupportingVertexWithoutMargin(-vec*m_transB.getBasis()));
return supVertexA - supVertexB;
}
void btMinkowskiSumShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
{
- //todo: could make recursive use of batching. probably this shape is not used frequently.
+ ///@todo: could make recursive use of batching. probably this shape is not used frequently.
for (int i=0;i<numVectors;i++)
{
supportVerticesOut[i] = localGetSupportingVertexWithoutMargin(vectors[i]);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h
index f9c8427c2f3..6f637fbf40b 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h
@@ -46,8 +46,6 @@ public:
const btTransform& GetTransformB()const { return m_transB;}
- virtual int getShapeType() const { return MINKOWSKI_SUM_SHAPE_PROXYTYPE; }
-
virtual btScalar getMargin() const;
const btConvexShape* getShapeA() const { return m_shapeA;}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
index c709205efc2..9423505290d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
@@ -18,8 +18,9 @@ subject to the following restrictions:
#include "LinearMath/btQuaternion.h"
btMultiSphereShape::btMultiSphereShape (const btVector3& inertiaHalfExtents,const btVector3* positions,const btScalar* radi,int numSpheres)
-:m_inertiaHalfExtents(inertiaHalfExtents)
+:btConvexInternalShape (), m_inertiaHalfExtents(inertiaHalfExtents)
{
+ m_shapeType = MULTI_SPHERE_SHAPE_PROXYTYPE;
btScalar startMargin = btScalar(1e30);
m_numSpheres = numSpheres;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h
index 45968f3947f..97309fbbed9 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h
@@ -62,7 +62,6 @@ public:
return m_radi[index];
}
- virtual int getShapeType() const { return MULTI_SPHERE_SHAPE_PROXYTYPE; }
virtual const char* getName()const
{
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h
index 2f108020cdf..d025a5c4450 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h
@@ -31,10 +31,12 @@ public:
BT_DECLARE_ALIGNED_ALLOCATOR();
- btMultimaterialTriangleMeshShape(): btBvhTriangleMeshShape() {}
+ btMultimaterialTriangleMeshShape(): btBvhTriangleMeshShape() {m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;}
btMultimaterialTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true):
btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, buildBvh)
{
+ m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;
+
btVector3 m_triangle[3];
const unsigned char *vertexbase;
int numverts;
@@ -67,6 +69,8 @@ public:
btMultimaterialTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax, bool buildBvh = true):
btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, bvhAabbMin, bvhAabbMax, buildBvh)
{
+ m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;
+
btVector3 m_triangle[3];
const unsigned char *vertexbase;
int numverts;
@@ -107,11 +111,6 @@ public:
m_materialLookup = NULL;
*/
}
- virtual int getShapeType() const
- {
- return MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;
- }
-
//debugging
virtual const char* getName()const {return "MULTIMATERIALTRIANGLEMESH";}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp
index a248c55b571..3e73059394c 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp
@@ -319,19 +319,19 @@ void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int f
{
int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
- btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
-#ifdef DEBUG_PATCH_COLORS
- btVector3 mycolor = color[index&3];
- graphicsbase[8] = mycolor.getX();
- graphicsbase[9] = mycolor.getY();
- graphicsbase[10] = mycolor.getZ();
-#endif //DEBUG_PATCH_COLORS
-
-
- triangleVerts[j] = btVector3(
- graphicsbase[0]*meshScaling.getX(),
- graphicsbase[1]*meshScaling.getY(),
- graphicsbase[2]*meshScaling.getZ());
+ if (type == PHY_FLOAT)
+ {
+ float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
+ triangleVerts[j] = btVector3(
+ graphicsbase[0]*meshScaling.getX(),
+ graphicsbase[1]*meshScaling.getY(),
+ graphicsbase[2]*meshScaling.getZ());
+ }
+ else
+ {
+ double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
+ triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*meshScaling.getX()), btScalar(graphicsbase[1]*meshScaling.getY()), btScalar(graphicsbase[2]*meshScaling.getZ()));
+ }
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
index 71c3af38a02..7a79ac25791 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
@@ -15,8 +15,8 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
-btPolyhedralConvexShape::btPolyhedralConvexShape()
-:m_localAabbMin(1,1,1),
+btPolyhedralConvexShape::btPolyhedralConvexShape() :btConvexInternalShape(),
+m_localAabbMin(1,1,1),
m_localAabbMax(-1,-1,-1),
m_isLocalAabbValid(false),
m_optionalHull(0)
@@ -25,7 +25,6 @@ m_optionalHull(0)
}
-
btVector3 btPolyhedralConvexShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
{
int i;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
index 4c4ce7feaa7..7567a42d3ba 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
@@ -16,7 +16,6 @@ subject to the following restrictions:
#ifndef BU_SHAPE
#define BU_SHAPE
-#include "LinearMath/btPoint3.h"
#include "LinearMath/btMatrix3x3.h"
#include "LinearMath/btAabbUtil2.h"
#include "btConvexInternalShape.h"
@@ -36,12 +35,28 @@ public:
btPolyhedralConvexShape();
//brute force implementations
+
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+
virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+ void setCachedLocalAabb (const btVector3& aabbMin, const btVector3& aabbMax)
+ {
+ m_isLocalAabbValid = true;
+ m_localAabbMin = aabbMin;
+ m_localAabbMax = aabbMax;
+ }
+
+ inline void getCachedLocalAabb (btVector3& aabbMin, btVector3& aabbMax) const
+ {
+ btAssert(m_isLocalAabbValid);
+ aabbMin = m_localAabbMin;
+ aabbMax = m_localAabbMax;
+ }
+
inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const
{
@@ -59,13 +74,13 @@ public:
virtual int getNumVertices() const = 0 ;
virtual int getNumEdges() const = 0;
- virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const = 0;
- virtual void getVertex(int i,btPoint3& vtx) const = 0;
+ virtual void getEdge(int i,btVector3& pa,btVector3& pb) const = 0;
+ virtual void getVertex(int i,btVector3& vtx) const = 0;
virtual int getNumPlanes() const = 0;
- virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const = 0;
+ virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const = 0;
// virtual int getIndex(int i) const = 0 ;
- virtual bool isInside(const btPoint3& pt,btScalar tolerance) const = 0;
+ virtual bool isInside(const btVector3& pt,btScalar tolerance) const = 0;
/// optional Hull is for optional Separating Axis Test Hull collision detection, see Hull.cpp
class Hull* m_optionalHull;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp
index 2b81a02b557..1fac1538769 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp
@@ -15,11 +15,10 @@ subject to the following restrictions:
#include "btScaledBvhTriangleMeshShape.h"
-btScaledBvhTriangleMeshShape::btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,btVector3 localScaling)
-:m_bvhTriMeshShape(childShape),
-m_localScaling(localScaling)
+btScaledBvhTriangleMeshShape::btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling)
+:m_localScaling(localScaling),m_bvhTriMeshShape(childShape)
{
-
+ m_shapeType = SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE;
}
btScaledBvhTriangleMeshShape::~btScaledBvhTriangleMeshShape()
@@ -35,7 +34,7 @@ class btScaledTriangleCallback : public btTriangleCallback
public:
- btScaledTriangleCallback(btTriangleCallback* originalCallback,btVector3 localScaling)
+ btScaledTriangleCallback(btTriangleCallback* originalCallback,const btVector3& localScaling)
:m_originalCallback(originalCallback),
m_localScaling(localScaling)
{
@@ -94,7 +93,7 @@ void btScaledBvhTriangleMeshShape::getAabb(const btTransform& trans,btVector3& a
btMatrix3x3 abs_b = trans.getBasis().absolute();
- btPoint3 center = trans(localCenter);
+ btVector3 center = trans(localCenter);
btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
abs_b[1].dot(localHalfExtents),
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h
index 0a1ef8ce5cb..5da6fe8bc95 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h
@@ -32,15 +32,10 @@ ATTRIBUTE_ALIGNED16(class) btScaledBvhTriangleMeshShape : public btConcaveShape
public:
- btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,btVector3 localScaling);
+ btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling);
virtual ~btScaledBvhTriangleMeshShape();
- virtual int getShapeType() const
- {
- //use un-used 'FAST_CONCAVE_MESH_PROXYTYPE' for now, later add SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE to btBroadphaseProxy.h
- return SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE;
- }
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
virtual void setLocalScaling(const btVector3& scaling);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp
index 15cfe432e27..cab7b277289 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.cpp
@@ -18,12 +18,6 @@ subject to the following restrictions:
#include "LinearMath/btQuaternion.h"
-
-btSphereShape ::btSphereShape (btScalar radius)
-{
- m_implicitShapeDimensions.setX(radius);
-}
-
btVector3 btSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
{
(void)vec;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h
index a6d01cdca9d..bf163d3b501 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btSphereShape.h
@@ -27,8 +27,12 @@ ATTRIBUTE_ALIGNED16(class) btSphereShape : public btConvexInternalShape
public:
BT_DECLARE_ALIGNED_ALLOCATOR();
- btSphereShape (btScalar radius);
-
+ btSphereShape (btScalar radius) : btConvexInternalShape ()
+ {
+ m_shapeType = SPHERE_SHAPE_PROXYTYPE;
+ m_implicitShapeDimensions.setX(radius);
+ m_collisionMargin = radius;
+ }
virtual btVector3 localGetSupportingVertex(const btVector3& vec)const;
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
@@ -40,7 +44,6 @@ public:
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
- virtual int getShapeType() const { return SPHERE_SHAPE_PROXYTYPE; }
btScalar getRadius() const { return m_implicitShapeDimensions.getX() * m_localScaling.getX();}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp
index 3c98ca08ddc..17b8776d459 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp
@@ -19,10 +19,11 @@ subject to the following restrictions:
btStaticPlaneShape::btStaticPlaneShape(const btVector3& planeNormal,btScalar planeConstant)
-:m_planeNormal(planeNormal.normalized()),
+: btConcaveShape (), m_planeNormal(planeNormal.normalized()),
m_planeConstant(planeConstant),
m_localScaling(btScalar(0.),btScalar(0.),btScalar(0.))
{
+ m_shapeType = STATIC_PLANE_PROXYTYPE;
// btAssert( btFuzzyZero(m_planeNormal.length() - btScalar(1.)) );
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h
index ddebca73dea..a496013c077 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h
@@ -36,11 +36,6 @@ public:
virtual ~btStaticPlaneShape();
- virtual int getShapeType() const
- {
- return STATIC_PLANE_PROXYTYPE;
- }
-
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h
index 85020dd3f58..e61b11499d4 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h
@@ -18,16 +18,9 @@ subject to the following restrictions:
#include "LinearMath/btVector3.h"
#include "btTriangleCallback.h"
+#include "btConcaveShape.h"
+
-/// PHY_ScalarType enumerates possible scalar types.
-/// See the btStridingMeshInterface for its use
-typedef enum PHY_ScalarType {
- PHY_FLOAT,
- PHY_DOUBLE,
- PHY_INTEGER,
- PHY_SHORT,
- PHY_FIXEDPOINT88
-} PHY_ScalarType;
/// The btStridingMeshInterface is the interface class for high performance generic access to triangle meshes, used in combination with btBvhTriangleMeshShape and some other collision shapes.
/// Using index striding of 3*sizeof(integer) it can use triangle arrays, using index striding of 1*sizeof(integer) it can handle triangle strips.
@@ -77,8 +70,16 @@ class btStridingMeshInterface
virtual void preallocateIndices(int numindices)=0;
virtual bool hasPremadeAabb() const { return false; }
- virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const {}
- virtual void getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const {}
+ virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const
+ {
+ (void) aabbMin;
+ (void) aabbMax;
+ }
+ virtual void getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const
+ {
+ (void) aabbMin;
+ (void) aabbMax;
+ }
const btVector3& getScaling() const {
return m_scaling;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp
index 3aa1eda9964..7fd8fb4691b 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp
@@ -16,35 +16,40 @@ subject to the following restrictions:
#include "btTetrahedronShape.h"
#include "LinearMath/btMatrix3x3.h"
-btBU_Simplex1to4::btBU_Simplex1to4()
-:m_numVertices(0)
+btBU_Simplex1to4::btBU_Simplex1to4() : btPolyhedralConvexShape (),
+m_numVertices(0)
{
+ m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE;
}
-btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0)
-:m_numVertices(0)
+btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0) : btPolyhedralConvexShape (),
+m_numVertices(0)
{
+ m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE;
addVertex(pt0);
}
-btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1)
-:m_numVertices(0)
+btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1) : btPolyhedralConvexShape (),
+m_numVertices(0)
{
+ m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE;
addVertex(pt0);
addVertex(pt1);
}
-btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2)
-:m_numVertices(0)
+btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2) : btPolyhedralConvexShape (),
+m_numVertices(0)
{
+ m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE;
addVertex(pt0);
addVertex(pt1);
addVertex(pt2);
}
-btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2,const btPoint3& pt3)
-:m_numVertices(0)
+btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2,const btVector3& pt3) : btPolyhedralConvexShape (),
+m_numVertices(0)
{
+ m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE;
addVertex(pt0);
addVertex(pt1);
addVertex(pt2);
@@ -55,7 +60,7 @@ btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const
-void btBU_Simplex1to4::addVertex(const btPoint3& pt)
+void btBU_Simplex1to4::addVertex(const btVector3& pt)
{
m_vertices[m_numVertices++] = pt;
@@ -87,7 +92,7 @@ int btBU_Simplex1to4::getNumEdges() const
return 0;
}
-void btBU_Simplex1to4::getEdge(int i,btPoint3& pa,btPoint3& pb) const
+void btBU_Simplex1to4::getEdge(int i,btVector3& pa,btVector3& pb) const
{
switch (m_numVertices)
@@ -151,7 +156,7 @@ void btBU_Simplex1to4::getEdge(int i,btPoint3& pa,btPoint3& pb) const
}
-void btBU_Simplex1to4::getVertex(int i,btPoint3& vtx) const
+void btBU_Simplex1to4::getVertex(int i,btVector3& vtx) const
{
vtx = m_vertices[i];
}
@@ -178,7 +183,7 @@ int btBU_Simplex1to4::getNumPlanes() const
}
-void btBU_Simplex1to4::getPlane(btVector3&, btPoint3& ,int ) const
+void btBU_Simplex1to4::getPlane(btVector3&, btVector3& ,int ) const
{
}
@@ -188,7 +193,7 @@ int btBU_Simplex1to4::getIndex(int ) const
return 0;
}
-bool btBU_Simplex1to4::isInside(const btPoint3& ,btScalar ) const
+bool btBU_Simplex1to4::isInside(const btVector3& ,btScalar ) const
{
return false;
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h
index 09272d61dc2..114ae288bb0 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h
@@ -27,15 +27,15 @@ class btBU_Simplex1to4 : public btPolyhedralConvexShape
protected:
int m_numVertices;
- btPoint3 m_vertices[4];
+ btVector3 m_vertices[4];
public:
btBU_Simplex1to4();
- btBU_Simplex1to4(const btPoint3& pt0);
- btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1);
- btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2);
- btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2,const btPoint3& pt3);
+ btBU_Simplex1to4(const btVector3& pt0);
+ btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1);
+ btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2);
+ btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2,const btVector3& pt3);
void reset()
@@ -44,9 +44,8 @@ public:
}
- virtual int getShapeType() const{ return TETRAHEDRAL_SHAPE_PROXYTYPE; }
- void addVertex(const btPoint3& pt);
+ void addVertex(const btVector3& pt);
//PolyhedralConvexShape interface
@@ -54,17 +53,17 @@ public:
virtual int getNumEdges() const;
- virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const;
+ virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
- virtual void getVertex(int i,btPoint3& vtx) const;
+ virtual void getVertex(int i,btVector3& vtx) const;
virtual int getNumPlanes() const;
- virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i) const;
+ virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i) const;
virtual int getIndex(int i) const;
- virtual bool isInside(const btPoint3& pt,btScalar tolerance) const;
+ virtual bool isInside(const btVector3& pt,btScalar tolerance) const;
///getName is for debugging
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h
index c739fc11e8f..adca38041b2 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleBuffer.h
@@ -28,7 +28,7 @@ struct btTriangle
int m_triangleIndex;
};
-///btTriangleBuffer can be useful to collect and store overlapping triangles between AABB and concave objects that support 'processAllTriangles'
+///The btTriangleBuffer callback can be useful to collect and store overlapping triangles between AABB and concave objects that support 'processAllTriangles'
///Example usage of this class:
/// btTriangleBuffer triBuf;
/// concaveShape->processAllTriangles(&triBuf,aabbMin, aabbMax);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp
index b962829041a..5f292532861 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp
@@ -82,7 +82,8 @@ bool btTriangleIndexVertexArray::hasPremadeAabb() const
return (m_hasAabb == 1);
}
-void btTriangleIndexVertexArray::setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax )
+
+void btTriangleIndexVertexArray::setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const
{
m_aabbMin = aabbMin;
m_aabbMax = aabbMax;
@@ -95,3 +96,4 @@ void btTriangleIndexVertexArray::getPremadeAabb(btVector3* aabbMin, btVector3* a
*aabbMax = m_aabbMax;
}
+
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h
index e546675f802..eb79ff5e47d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h
@@ -52,9 +52,9 @@ ATTRIBUTE_ALIGNED16( class) btTriangleIndexVertexArray : public btStridingMeshIn
protected:
IndexedMeshArray m_indexedMeshes;
int m_pad[2];
- int m_hasAabb; // using int instead of bool to maintain alignment
- btVector3 m_aabbMin;
- btVector3 m_aabbMax;
+ mutable int m_hasAabb; // using int instead of bool to maintain alignment
+ mutable btVector3 m_aabbMin;
+ mutable btVector3 m_aabbMax;
public:
@@ -106,7 +106,7 @@ public:
virtual void preallocateIndices(int numindices){(void) numindices;}
virtual bool hasPremadeAabb() const;
- virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax );
+ virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const;
virtual void getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const;
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
index 492854ff646..abefa71250a 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
@@ -1,3 +1,4 @@
+
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp
index 29d26316316..5dcfa51c280 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp
@@ -35,13 +35,13 @@ m_weldingThreshold(0.0)
if (m_use32bitIndices)
{
m_indexedMeshes[0].m_numTriangles = m_32bitIndices.size()/3;
- m_indexedMeshes[0].m_triangleIndexBase = (unsigned char*) &m_32bitIndices[0];
+ m_indexedMeshes[0].m_triangleIndexBase = 0;
m_indexedMeshes[0].m_indexType = PHY_INTEGER;
m_indexedMeshes[0].m_triangleIndexStride = 3*sizeof(int);
} else
{
m_indexedMeshes[0].m_numTriangles = m_16bitIndices.size()/3;
- m_indexedMeshes[0].m_triangleIndexBase = (unsigned char*) &m_16bitIndices[0];
+ m_indexedMeshes[0].m_triangleIndexBase = 0;
m_indexedMeshes[0].m_indexType = PHY_SHORT;
m_indexedMeshes[0].m_triangleIndexStride = 3*sizeof(short int);
}
@@ -49,12 +49,12 @@ m_weldingThreshold(0.0)
if (m_use4componentVertices)
{
m_indexedMeshes[0].m_numVertices = m_4componentVertices.size();
- m_indexedMeshes[0].m_vertexBase = (unsigned char*)&m_4componentVertices[0];
+ m_indexedMeshes[0].m_vertexBase = 0;
m_indexedMeshes[0].m_vertexStride = sizeof(btVector3);
} else
{
m_indexedMeshes[0].m_numVertices = m_3componentVertices.size()/3;
- m_indexedMeshes[0].m_vertexBase = (unsigned char*)&m_3componentVertices[0];
+ m_indexedMeshes[0].m_vertexBase = 0;
m_indexedMeshes[0].m_vertexStride = 3*sizeof(btScalar);
}
@@ -74,17 +74,21 @@ void btTriangleMesh::addIndex(int index)
}
}
-int btTriangleMesh::findOrAddVertex(const btVector3& vertex)
+
+int btTriangleMesh::findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices)
{
//return index of new/existing vertex
- //todo: could use acceleration structure for this
+ ///@todo: could use acceleration structure for this
if (m_use4componentVertices)
{
- for (int i=0;i< m_4componentVertices.size();i++)
- {
- if ((m_4componentVertices[i]-vertex).length2() <= m_weldingThreshold)
+ if (removeDuplicateVertices)
+ {
+ for (int i=0;i< m_4componentVertices.size();i++)
{
- return i;
+ if ((m_4componentVertices[i]-vertex).length2() <= m_weldingThreshold)
+ {
+ return i;
+ }
}
}
m_indexedMeshes[0].m_numVertices++;
@@ -96,17 +100,20 @@ int btTriangleMesh::findOrAddVertex(const btVector3& vertex)
} else
{
- for (int i=0;i< m_3componentVertices.size();i+=3)
+ if (removeDuplicateVertices)
{
- btVector3 vtx(m_3componentVertices[i],m_3componentVertices[i+1],m_3componentVertices[i+2]);
- if ((vtx-vertex).length2() <= m_weldingThreshold)
+ for (int i=0;i< m_3componentVertices.size();i+=3)
{
- return i/3;
+ btVector3 vtx(m_3componentVertices[i],m_3componentVertices[i+1],m_3componentVertices[i+2]);
+ if ((vtx-vertex).length2() <= m_weldingThreshold)
+ {
+ return i/3;
+ }
}
- }
- m_3componentVertices.push_back(vertex.getX());
- m_3componentVertices.push_back(vertex.getY());
- m_3componentVertices.push_back(vertex.getZ());
+ }
+ m_3componentVertices.push_back((float)vertex.getX());
+ m_3componentVertices.push_back((float)vertex.getY());
+ m_3componentVertices.push_back((float)vertex.getZ());
m_indexedMeshes[0].m_numVertices++;
m_indexedMeshes[0].m_vertexBase = (unsigned char*)&m_3componentVertices[0];
return (m_3componentVertices.size()/3)-1;
@@ -114,13 +121,12 @@ int btTriangleMesh::findOrAddVertex(const btVector3& vertex)
}
-void btTriangleMesh::addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2)
+void btTriangleMesh::addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2,bool removeDuplicateVertices)
{
m_indexedMeshes[0].m_numTriangles++;
-
- addIndex(findOrAddVertex(vertex0));
- addIndex(findOrAddVertex(vertex1));
- addIndex(findOrAddVertex(vertex2));
+ addIndex(findOrAddVertex(vertex0,removeDuplicateVertices));
+ addIndex(findOrAddVertex(vertex1,removeDuplicateVertices));
+ addIndex(findOrAddVertex(vertex2,removeDuplicateVertices));
}
int btTriangleMesh::getNumTriangles() const
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h
index 1f51b2f2c87..f06fbb7c22d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h
@@ -25,7 +25,6 @@ subject to the following restrictions:
///It allows either 32bit or 16bit indices, and 4 (x-y-z-w) or 3 (x-y-z) component vertices.
///If you want to share triangle/index data between graphics mesh and collision mesh (btBvhTriangleMeshShape), you can directly use btTriangleIndexVertexArray or derive your own class from btStridingMeshInterface.
///Performance of btTriangleMesh and btTriangleIndexVertexArray used in a btBvhTriangleMeshShape is the same.
-///It has a brute-force option to weld together closeby vertices.
class btTriangleMesh : public btTriangleIndexVertexArray
{
btAlignedObjectArray<btVector3> m_4componentVertices;
@@ -42,7 +41,7 @@ class btTriangleMesh : public btTriangleIndexVertexArray
btTriangleMesh (bool use32bitIndices=true,bool use4componentVertices=true);
- int findOrAddVertex(const btVector3& vertex);
+ int findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices);
void addIndex(int index);
bool getUse32bitIndices() const
@@ -54,8 +53,9 @@ class btTriangleMesh : public btTriangleIndexVertexArray
{
return m_use4componentVertices;
}
-
- void addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2);
+ ///By default addTriangle won't search for duplicate vertices, because the search is very slow for large triangle meshes.
+ ///In general it is better to directly use btTriangleIndexVertexArray instead.
+ void addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2, bool removeDuplicateVertices=false);
int getNumTriangles() const;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
index 0a2c77096d1..1bd7e84a4e7 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
@@ -22,8 +22,9 @@ subject to the following restrictions:
btTriangleMeshShape::btTriangleMeshShape(btStridingMeshInterface* meshInterface)
-: m_meshInterface(meshInterface)
+: btConcaveShape (), m_meshInterface(meshInterface)
{
+ m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
if(meshInterface->hasPremadeAabb())
{
meshInterface->getPremadeAabb(&m_localAabbMin, &m_localAabbMax);
@@ -52,7 +53,7 @@ void btTriangleMeshShape::getAabb(const btTransform& trans,btVector3& aabbMin,bt
btMatrix3x3 abs_b = trans.getBasis().absolute();
- btPoint3 center = trans(localCenter);
+ btVector3 center = trans(localCenter);
btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
abs_b[1].dot(localHalfExtents),
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h
index c9eabafe290..53d65799001 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h
@@ -40,7 +40,7 @@ public:
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const
{
- assert(0);
+ btAssert(0);
return localGetSupportingVertex(vec);
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h
index ba7aa0c32a0..4bfb0b9e881 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h
@@ -40,17 +40,13 @@ public:
{
vert = m_vertices1[index];
}
- virtual int getShapeType() const
- {
- return TRIANGLE_SHAPE_PROXYTYPE;
- }
virtual int getNumEdges() const
{
return 3;
}
- virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const
+ virtual void getEdge(int i,btVector3& pa,btVector3& pb) const
{
getVertex(i,pa);
getVertex((i+1)%3,pb);
@@ -83,15 +79,16 @@ public:
- btTriangleShape(const btVector3& p0,const btVector3& p1,const btVector3& p2)
+ btTriangleShape(const btVector3& p0,const btVector3& p1,const btVector3& p2) : btPolyhedralConvexShape ()
{
+ m_shapeType = TRIANGLE_SHAPE_PROXYTYPE;
m_vertices1[0] = p0;
m_vertices1[1] = p1;
m_vertices1[2] = p2;
}
- virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i) const
+ virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i) const
{
getPlaneEquation(i,planeNormal,planeSupport);
}
@@ -107,7 +104,7 @@ public:
normal.normalize();
}
- virtual void getPlaneEquation(int i, btVector3& planeNormal,btPoint3& planeSupport) const
+ virtual void getPlaneEquation(int i, btVector3& planeNormal,btVector3& planeSupport) const
{
(void)i;
calcNormal(planeNormal);
@@ -121,7 +118,7 @@ public:
inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
}
- virtual bool isInside(const btPoint3& pt,btScalar tolerance) const
+ virtual bool isInside(const btVector3& pt,btScalar tolerance) const
{
btVector3 normal;
calcNormal(normal);
@@ -135,7 +132,7 @@ public:
int i;
for (i=0;i<3;i++)
{
- btPoint3 pa,pb;
+ btVector3 pa,pb;
getEdge(i,pa,pb);
btVector3 edge = pb-pa;
btVector3 edgeNormal = edge.cross(normal);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp
index ef340286cb0..4c1c716d519 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp
@@ -16,9 +16,10 @@ subject to the following restrictions:
#include "btUniformScalingShape.h"
btUniformScalingShape::btUniformScalingShape( btConvexShape* convexChildShape,btScalar uniformScalingFactor):
-m_childConvexShape(convexChildShape),
+btConvexShape (), m_childConvexShape(convexChildShape),
m_uniformScalingFactor(uniformScalingFactor)
{
+ m_shapeType = UNIFORM_SCALING_SHAPE_PROXYTYPE;
}
btUniformScalingShape::~btUniformScalingShape()
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h
index 1e17fc8e198..945976ac036 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h
@@ -61,7 +61,6 @@ class btUniformScalingShape : public btConvexShape
return "UniformScalingShape";
}
- virtual int getShapeType() const { return UNIFORM_SCALING_SHAPE_PROXYTYPE; }
///////////////////////////
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btBoxCollision.h b/extern/bullet2/src/BulletCollision/Gimpact/btBoxCollision.h
index cf43f487e24..827a3c89587 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btBoxCollision.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btBoxCollision.h
@@ -26,9 +26,6 @@ subject to the following restrictions:
#include "LinearMath/btTransform.h"
-/*! \defgroup BOUND_AABB_OPERATIONS
-*/
-//! @{
///Swap numbers
#define BT_SWAP_NUMBERS(a,b){ \
@@ -41,7 +38,7 @@ subject to the following restrictions:
#define BT_MAX(a,b) (a<b?b:a)
#define BT_MIN(a,b) (a>b?b:a)
-#define BT_GREATER(x, y) fabsf(x) > (y)
+#define BT_GREATER(x, y) btFabs(x) > (y)
#define BT_MAX3(a,b,c) BT_MAX(a,BT_MAX(b,c))
#define BT_MIN3(a,b,c) BT_MIN(a,BT_MIN(b,c))
@@ -181,7 +178,7 @@ public:
{
for(j=0;j<3;j++ )
{
- m_AR[i][j] = 1e-6f + fabsf(m_R1to0[i][j]);
+ m_AR[i][j] = 1e-6f + btFabs(m_R1to0[i][j]);
}
}
@@ -646,6 +643,5 @@ SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform & t1,const btT
}
-//! @}
#endif // GIM_BOX_COLLISION_H_INCLUDED
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btClipPolygon.h b/extern/bullet2/src/BulletCollision/Gimpact/btClipPolygon.h
index 28c03b7e039..5de391a7561 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btClipPolygon.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btClipPolygon.h
@@ -27,9 +27,6 @@ subject to the following restrictions:
#include "LinearMath/btTransform.h"
#include "LinearMath/btGeometryUtil.h"
-/*! \addtogroup GEOMETRIC_OPERATIONS
-*/
-//! @{
SIMD_FORCE_INLINE btScalar bt_distance_point_plane(const btVector4 & plane,const btVector3 &point)
{
@@ -181,6 +178,5 @@ SIMD_FORCE_INLINE int bt_plane_clip_triangle(
-//! @}
#endif // GIM_TRI_COLLISION_H_INCLUDED
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btContactProcessing.cpp b/extern/bullet2/src/BulletCollision/Gimpact/btContactProcessing.cpp
index faba2d8a542..c3b697bdd1e 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btContactProcessing.cpp
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btContactProcessing.cpp
@@ -103,12 +103,12 @@ void btContactArray::merge_contacts(
push_back(contacts[keycontacts[0].m_value]);
- BT_CONTACT * pcontact = &(*this)[0];
+ GIM_CONTACT * pcontact = &(*this)[0];
for( i=1;i<keycontacts.size();i++)
{
key = keycontacts[i].m_key;
- const BT_CONTACT * scontact = &contacts[keycontacts[i].m_value];
+ const GIM_CONTACT * scontact = &contacts[keycontacts[i].m_value];
if(last_key == key)//same points
{
@@ -158,7 +158,7 @@ void btContactArray::merge_contacts_unique(const btContactArray & contacts)
return;
}
- BT_CONTACT average_contact = contacts[0];
+ GIM_CONTACT average_contact = contacts[0];
for (int i=1;i<contacts.size() ;i++ )
{
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btContactProcessing.h b/extern/bullet2/src/BulletCollision/Gimpact/btContactProcessing.h
index 0cfd013b962..4b0b70293b4 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btContactProcessing.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btContactProcessing.h
@@ -29,11 +29,6 @@ subject to the following restrictions:
#include "btTriangleShapeEx.h"
-/*! \defgroup CONTACTS
-\brief
-Functions for managing and sorting contacts resulting from a collision query.
-*/
-//! @{
/**
Configuration var for applying interpolation of contact normals
@@ -42,8 +37,9 @@ Configuration var for applying interpolation of contact normals
#define CONTACT_DIFF_EPSILON 0.00001f
-/// Structure for collision results
-class BT_CONTACT
+///The GIM_CONTACT is an internal GIMPACT structure, similar to btManifoldPoint.
+///@todo: remove and replace GIM_CONTACT by btManifoldPoint.
+class GIM_CONTACT
{
public:
btVector3 m_point;
@@ -53,11 +49,11 @@ public:
int m_feature1;//Face number
int m_feature2;//Face number
public:
- BT_CONTACT()
+ GIM_CONTACT()
{
}
- BT_CONTACT(const BT_CONTACT & contact):
+ GIM_CONTACT(const GIM_CONTACT & contact):
m_point(contact.m_point),
m_normal(contact.m_normal),
m_depth(contact.m_depth),
@@ -66,7 +62,7 @@ public:
{
}
- BT_CONTACT(const btVector3 &point,const btVector3 & normal,
+ GIM_CONTACT(const btVector3 &point,const btVector3 & normal,
btScalar depth, int feature1, int feature2):
m_point(point),
m_normal(normal),
@@ -112,7 +108,7 @@ public:
};
-class btContactArray:public btAlignedObjectArray<BT_CONTACT>
+class btContactArray:public btAlignedObjectArray<GIM_CONTACT>
{
public:
btContactArray()
@@ -124,11 +120,11 @@ public:
const btVector3 &point,const btVector3 & normal,
btScalar depth, int feature1, int feature2)
{
- push_back( BT_CONTACT(point,normal,depth,feature1,feature2) );
+ push_back( GIM_CONTACT(point,normal,depth,feature1,feature2) );
}
SIMD_FORCE_INLINE void push_triangle_contacts(
- const BT_TRIANGLE_CONTACT & tricontact,
+ const GIM_TRIANGLE_CONTACT & tricontact,
int feature1,int feature2)
{
for(int i = 0;i<tricontact.m_point_count ;i++ )
@@ -145,5 +141,5 @@ public:
void merge_contacts_unique(const btContactArray & contacts);
};
-//! @}
+
#endif // GIM_CONTACT_H_INCLUDED
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactBvh.cpp b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactBvh.cpp
index b07926c30dc..38fed6b4fd2 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactBvh.cpp
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactBvh.cpp
@@ -65,7 +65,7 @@ float btGImpactBvh::getAverageTreeCollisionTime()
/////////////////////// btBvhTree /////////////////////////////////
int btBvhTree::_calc_splitting_axis(
- BT_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex)
+ GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex)
{
int i;
@@ -97,7 +97,7 @@ int btBvhTree::_calc_splitting_axis(
int btBvhTree::_sort_and_calc_splitting_index(
- BT_BVH_DATA_ARRAY & primitive_boxes, int startIndex,
+ GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,
int endIndex, int splitAxis)
{
int i;
@@ -150,15 +150,14 @@ int btBvhTree::_sort_and_calc_splitting_index(
splitIndex = startIndex+ (numIndices>>1);
}
- bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex));
- btAssert(!unbal);
+ btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex))));
return splitIndex;
}
-void btBvhTree::_build_sub_tree(BT_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex)
+void btBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex)
{
int curIndex = m_num_nodes;
m_num_nodes++;
@@ -211,7 +210,7 @@ void btBvhTree::_build_sub_tree(BT_BVH_DATA_ARRAY & primitive_boxes, int startIn
//! stackless build tree
void btBvhTree::build_tree(
- BT_BVH_DATA_ARRAY & primitive_boxes)
+ GIM_BVH_DATA_ARRAY & primitive_boxes)
{
// initialize node count to 0
m_num_nodes = 0;
@@ -236,7 +235,7 @@ void btGImpactBvh::refit()
}
else
{
- //const BT_BVH_TREE_NODE * nodepointer = get_node_pointer(nodecount);
+ //const GIM_BVH_TREE_NODE * nodepointer = get_node_pointer(nodecount);
//get left bound
btAABB bound;
bound.invalidate();
@@ -266,7 +265,7 @@ void btGImpactBvh::refit()
void btGImpactBvh::buildSet()
{
//obtain primitive boxes
- BT_BVH_DATA_ARRAY primitive_boxes;
+ GIM_BVH_DATA_ARRAY primitive_boxes;
primitive_boxes.resize(m_primitive_manager->get_primitive_count());
for (int i = 0;i<primitive_boxes.size() ;i++ )
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactBvh.h b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactBvh.h
index 1907efc2463..b432b615f8a 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactBvh.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactBvh.h
@@ -32,29 +32,23 @@ subject to the following restrictions:
-/*! \defgroup BOX_TREES
-
-
-
-*/
-//! @{
//! Overlapping pair
-struct BT_PAIR
+struct GIM_PAIR
{
int m_index1;
int m_index2;
- BT_PAIR()
+ GIM_PAIR()
{}
- BT_PAIR(const BT_PAIR & p)
+ GIM_PAIR(const GIM_PAIR & p)
{
m_index1 = p.m_index1;
m_index2 = p.m_index2;
}
- BT_PAIR(int index1, int index2)
+ GIM_PAIR(int index1, int index2)
{
m_index1 = index1;
m_index2 = index2;
@@ -62,7 +56,7 @@ struct BT_PAIR
};
//! A pairset array
-class btPairSet: public btAlignedObjectArray<BT_PAIR>
+class btPairSet: public btAlignedObjectArray<GIM_PAIR>
{
public:
btPairSet()
@@ -71,32 +65,32 @@ public:
}
inline void push_pair(int index1,int index2)
{
- push_back(BT_PAIR(index1,index2));
+ push_back(GIM_PAIR(index1,index2));
}
inline void push_pair_inv(int index1,int index2)
{
- push_back(BT_PAIR(index2,index1));
+ push_back(GIM_PAIR(index2,index1));
}
};
-
-struct BT_BVH_DATA
+///GIM_BVH_DATA is an internal GIMPACT collision structure to contain axis aligned bounding box
+struct GIM_BVH_DATA
{
btAABB m_bound;
int m_data;
};
//! Node Structure for trees
-class BT_BVH_TREE_NODE
+class GIM_BVH_TREE_NODE
{
public:
btAABB m_bound;
protected:
int m_escapeIndexOrDataIndex;
public:
- BT_BVH_TREE_NODE()
+ GIM_BVH_TREE_NODE()
{
m_escapeIndexOrDataIndex = 0;
}
@@ -133,12 +127,12 @@ public:
};
-class BT_BVH_DATA_ARRAY:public btAlignedObjectArray<BT_BVH_DATA>
+class GIM_BVH_DATA_ARRAY:public btAlignedObjectArray<GIM_BVH_DATA>
{
};
-class BT_BVH_TREE_NODE_ARRAY:public btAlignedObjectArray<BT_BVH_TREE_NODE>
+class GIM_BVH_TREE_NODE_ARRAY:public btAlignedObjectArray<GIM_BVH_TREE_NODE>
{
};
@@ -150,15 +144,15 @@ class btBvhTree
{
protected:
int m_num_nodes;
- BT_BVH_TREE_NODE_ARRAY m_node_array;
+ GIM_BVH_TREE_NODE_ARRAY m_node_array;
protected:
int _sort_and_calc_splitting_index(
- BT_BVH_DATA_ARRAY & primitive_boxes,
+ GIM_BVH_DATA_ARRAY & primitive_boxes,
int startIndex, int endIndex, int splitAxis);
- int _calc_splitting_axis(BT_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
+ int _calc_splitting_axis(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
- void _build_sub_tree(BT_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
+ void _build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
public:
btBvhTree()
{
@@ -167,7 +161,7 @@ public:
//! prototype functions for box tree management
//!@{
- void build_tree(BT_BVH_DATA_ARRAY & primitive_boxes);
+ void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes);
SIMD_FORCE_INLINE void clearNodes()
{
@@ -218,7 +212,7 @@ public:
return m_node_array[nodeindex].getEscapeIndex();
}
- SIMD_FORCE_INLINE const BT_BVH_TREE_NODE * get_node_pointer(int index = 0) const
+ SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE * get_node_pointer(int index = 0) const
{
return &m_node_array[index];
}
@@ -382,12 +376,11 @@ public:
}
- SIMD_FORCE_INLINE const BT_BVH_TREE_NODE * get_node_pointer(int index = 0) const
+ SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE * get_node_pointer(int index = 0) const
{
return m_box_tree.get_node_pointer(index);
}
-//! @}
static float getAverageTreeCollisionTime();
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp
index 28ad18fbde2..4d6fa88f62d 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp
@@ -192,7 +192,7 @@ float btGImpactCollisionAlgorithm::getAverageTriangleCollisionTime()
btGImpactCollisionAlgorithm::btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
-: btCollisionAlgorithm(ci)
+: btActivatingCollisionAlgorithm(ci,body0,body1)
{
m_manifoldPtr = NULL;
m_convex_algorithm = NULL;
@@ -404,7 +404,7 @@ void btGImpactCollisionAlgorithm::collide_sat_triangles(btCollisionObject * body
btPrimitiveTriangle ptri0;
btPrimitiveTriangle ptri1;
- BT_TRIANGLE_CONTACT contact_data;
+ GIM_TRIANGLE_CONTACT contact_data;
shape0->lockChildShapes();
shape1->lockChildShapes();
@@ -540,7 +540,7 @@ void btGImpactCollisionAlgorithm::gimpact_vs_gimpact(
int i = pairset.size();
while(i--)
{
- BT_PAIR * pair = &pairset[i];
+ GIM_PAIR * pair = &pairset[i];
m_triface0 = pair->m_index1;
m_triface1 = pair->m_index2;
btCollisionShape * colshape0 = retriever0.getChildShape(m_triface0);
@@ -584,14 +584,15 @@ void btGImpactCollisionAlgorithm::gimpact_vs_shape(btCollisionObject * body0,
if(shape0->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE)
{
btGImpactMeshShape * meshshape0 = static_cast<btGImpactMeshShape *>(shape0);
- m_part0 = meshshape0->getMeshPartCount();
+ int& part = swapped ? m_part1 : m_part0;
+ part = meshshape0->getMeshPartCount();
- while(m_part0--)
+ while(part--)
{
gimpact_vs_shape(body0,
body1,
- meshshape0->getMeshPart(m_part0),
+ meshshape0->getMeshPart(part),
shape1,swapped);
}
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h
index c745b7ed5d8..453472aa034 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h
@@ -24,7 +24,7 @@ subject to the following restrictions:
#ifndef BVH_CONCAVE_COLLISION_ALGORITHM_H
#define BVH_CONCAVE_COLLISION_ALGORITHM_H
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h"
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
@@ -51,7 +51,7 @@ btCollisionDispatcher * dispatcher = static_cast<btCollisionDispatcher *>(m_dyna
btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher);
\endcode
*/
-class btGImpactCollisionAlgorithm : public btCollisionAlgorithm
+class btGImpactCollisionAlgorithm : public btActivatingCollisionAlgorithm
{
protected:
btCollisionAlgorithm * m_convex_algorithm;
@@ -67,7 +67,7 @@ protected:
//! Creates a new contact point
SIMD_FORCE_INLINE btPersistentManifold* newContactManifold(btCollisionObject* body0,btCollisionObject* body1)
{
- m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
+ m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
return m_manifoldPtr;
}
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp
index 0b1ef6acd83..ea1647a8129 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp
@@ -67,7 +67,7 @@ float btGImpactQuantizedBvh::getAverageTreeCollisionTime()
/////////////////////// btQuantizedBvhTree /////////////////////////////////
void btQuantizedBvhTree::calc_quantization(
- BT_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin)
+ GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin)
{
//calc globa box
btAABB global_bound;
@@ -86,7 +86,7 @@ void btQuantizedBvhTree::calc_quantization(
int btQuantizedBvhTree::_calc_splitting_axis(
- BT_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex)
+ GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex)
{
int i;
@@ -118,7 +118,7 @@ int btQuantizedBvhTree::_calc_splitting_axis(
int btQuantizedBvhTree::_sort_and_calc_splitting_index(
- BT_BVH_DATA_ARRAY & primitive_boxes, int startIndex,
+ GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,
int endIndex, int splitAxis)
{
int i;
@@ -171,15 +171,14 @@ int btQuantizedBvhTree::_sort_and_calc_splitting_index(
splitIndex = startIndex+ (numIndices>>1);
}
- bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex));
- btAssert(!unbal);
+ btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex))));
return splitIndex;
}
-void btQuantizedBvhTree::_build_sub_tree(BT_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex)
+void btQuantizedBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex)
{
int curIndex = m_num_nodes;
m_num_nodes++;
@@ -232,7 +231,7 @@ void btQuantizedBvhTree::_build_sub_tree(BT_BVH_DATA_ARRAY & primitive_boxes, in
//! stackless build tree
void btQuantizedBvhTree::build_tree(
- BT_BVH_DATA_ARRAY & primitive_boxes)
+ GIM_BVH_DATA_ARRAY & primitive_boxes)
{
calc_quantization(primitive_boxes);
// initialize node count to 0
@@ -258,7 +257,7 @@ void btGImpactQuantizedBvh::refit()
}
else
{
- //const BT_BVH_TREE_NODE * nodepointer = get_node_pointer(nodecount);
+ //const GIM_BVH_TREE_NODE * nodepointer = get_node_pointer(nodecount);
//get left bound
btAABB bound;
bound.invalidate();
@@ -288,7 +287,7 @@ void btGImpactQuantizedBvh::refit()
void btGImpactQuantizedBvh::buildSet()
{
//obtain primitive boxes
- BT_BVH_DATA_ARRAY primitive_boxes;
+ GIM_BVH_DATA_ARRAY primitive_boxes;
primitive_boxes.resize(m_primitive_manager->get_primitive_count());
for (int i = 0;i<primitive_boxes.size() ;i++ )
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h
index 3a4774b849d..e9cccac75f5 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h
@@ -29,12 +29,6 @@ subject to the following restrictions:
-/*! \defgroup BOX_TREES
-
-
-
-*/
-//! @{
///btQuantizedBvhNode is a compressed aabb node, 16 bytes.
@@ -100,7 +94,7 @@ ATTRIBUTE_ALIGNED16 (struct) BT_QUANTIZED_BVH_NODE
-class BT_QUANTIZED_BVH_NODE_ARRAY:public btAlignedObjectArray<BT_QUANTIZED_BVH_NODE>
+class GIM_QUANTIZED_BVH_NODE_ARRAY:public btAlignedObjectArray<BT_QUANTIZED_BVH_NODE>
{
};
@@ -112,19 +106,19 @@ class btQuantizedBvhTree
{
protected:
int m_num_nodes;
- BT_QUANTIZED_BVH_NODE_ARRAY m_node_array;
+ GIM_QUANTIZED_BVH_NODE_ARRAY m_node_array;
btAABB m_global_bound;
btVector3 m_bvhQuantization;
protected:
- void calc_quantization(BT_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin = btScalar(1.0) );
+ void calc_quantization(GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin = btScalar(1.0) );
int _sort_and_calc_splitting_index(
- BT_BVH_DATA_ARRAY & primitive_boxes,
+ GIM_BVH_DATA_ARRAY & primitive_boxes,
int startIndex, int endIndex, int splitAxis);
- int _calc_splitting_axis(BT_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
+ int _calc_splitting_axis(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
- void _build_sub_tree(BT_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
+ void _build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex);
public:
btQuantizedBvhTree()
{
@@ -133,7 +127,7 @@ public:
//! prototype functions for box tree management
//!@{
- void build_tree(BT_BVH_DATA_ARRAY & primitive_boxes);
+ void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes);
SIMD_FORCE_INLINE void quantizePoint(
unsigned short * quantizedpoint, const btVector3 & point) const
@@ -365,7 +359,6 @@ public:
return m_box_tree.get_node_pointer(index);
}
-//! @}
static float getAverageTreeCollisionTime();
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h
index 43f32bea5a1..05431cfce15 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h
@@ -105,6 +105,7 @@ protected:
public:
btGImpactShapeInterface()
{
+ m_shapeType=GIMPACT_SHAPE_PROXYTYPE;
m_localAABB.invalidate();
m_needs_update = true;
localScaling.setValue(1.f,1.f,1.f);
@@ -880,6 +881,8 @@ Set of btGImpactMeshShapePart parts
*/
class btGImpactMeshShape : public btGImpactShapeInterface
{
+ btStridingMeshInterface* m_meshInterface;
+
protected:
btAlignedObjectArray<btGImpactMeshShapePart*> m_mesh_parts;
void buildMeshParts(btStridingMeshInterface * meshInterface)
@@ -906,6 +909,7 @@ protected:
public:
btGImpactMeshShape(btStridingMeshInterface * meshInterface)
{
+ m_meshInterface = meshInterface;
buildMeshParts(meshInterface);
}
@@ -921,6 +925,15 @@ public:
}
+ btStridingMeshInterface* getMeshInterface()
+ {
+ return m_meshInterface;
+ }
+
+ const btStridingMeshInterface* getMeshInterface() const
+ {
+ return m_meshInterface;
+ }
int getMeshPartCount() const
{
@@ -1032,12 +1045,12 @@ public:
}
//! call when reading child shapes
- virtual void lockChildShapes()
+ virtual void lockChildShapes() const
{
btAssert(0);
}
- virtual void unlockChildShapes()
+ virtual void unlockChildShapes() const
{
btAssert(0);
}
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp b/extern/bullet2/src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp
index 4b4b5e20dd3..956fa0430e3 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp
@@ -251,16 +251,16 @@ bool btGenericPoolAllocator::freeMemory(void * pointer)
#define BT_DEFAULT_POOL_ELEMENT_SIZE 8
// main allocator
-class BT_STANDARD_ALLOCATOR: public btGenericPoolAllocator
+class GIM_STANDARD_ALLOCATOR: public btGenericPoolAllocator
{
public:
- BT_STANDARD_ALLOCATOR():btGenericPoolAllocator(BT_DEFAULT_POOL_ELEMENT_SIZE,BT_DEFAULT_POOL_SIZE)
+ GIM_STANDARD_ALLOCATOR():btGenericPoolAllocator(BT_DEFAULT_POOL_ELEMENT_SIZE,BT_DEFAULT_POOL_SIZE)
{
}
};
// global allocator
-BT_STANDARD_ALLOCATOR g_main_allocator;
+GIM_STANDARD_ALLOCATOR g_main_allocator;
void * btPoolAlloc(size_t size)
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGenericPoolAllocator.h b/extern/bullet2/src/BulletCollision/Gimpact/btGenericPoolAllocator.h
index 05b79a82516..e883bcd23d2 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGenericPoolAllocator.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGenericPoolAllocator.h
@@ -155,14 +155,9 @@ public:
-/*! \defgroup POOL_MEMORY_FUNCTIONS
-standar managed Memory functions. Memory pools are used.
-*/
-//! @{
void * btPoolAlloc(size_t size);
void * btPoolRealloc(void *ptr, size_t oldsize, size_t newsize);
void btPoolFree(void *ptr);
-//! @}
#endif
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGeometryOperations.h b/extern/bullet2/src/BulletCollision/Gimpact/btGeometryOperations.h
index f5800716a96..bc5a416ddb7 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGeometryOperations.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGeometryOperations.h
@@ -29,9 +29,6 @@ subject to the following restrictions:
-/*! \defgroup GEOMETRIC_OPERATIONS
-*/
-//! @{
#define PLANEDIREPSILON 0.0000001f
@@ -210,7 +207,6 @@ SIMD_FORCE_INLINE void bt_segment_collision(
-//! @}
#endif // GIM_VECTOR_H_INCLUDED
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btQuantization.h b/extern/bullet2/src/BulletCollision/Gimpact/btQuantization.h
index e9e6ad3d805..7faada61c95 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btQuantization.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btQuantization.h
@@ -29,9 +29,6 @@ subject to the following restrictions:
-/*! \defgroup GEOMETRIC_OPERATIONS
-*/
-//! @{
@@ -86,7 +83,6 @@ SIMD_FORCE_INLINE btVector3 bt_unquantize(
return vecOut;
}
-//! @}
#endif // GIM_VECTOR_H_INCLUDED
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btTriangleShapeEx.cpp b/extern/bullet2/src/BulletCollision/Gimpact/btTriangleShapeEx.cpp
index 0267f7e67c7..78696277c34 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btTriangleShapeEx.cpp
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btTriangleShapeEx.cpp
@@ -25,7 +25,7 @@ subject to the following restrictions:
-void BT_TRIANGLE_CONTACT::merge_points(const btVector4 & plane,
+void GIM_TRIANGLE_CONTACT::merge_points(const btVector4 & plane,
btScalar margin, const btVector3 * points, int point_count)
{
m_point_count = 0;
@@ -123,7 +123,7 @@ int btPrimitiveTriangle::clip_triangle(btPrimitiveTriangle & other, btVector3 *
return clipped_count;
}
-bool btPrimitiveTriangle::find_triangle_collision_clip_method(btPrimitiveTriangle & other, BT_TRIANGLE_CONTACT & contacts)
+bool btPrimitiveTriangle::find_triangle_collision_clip_method(btPrimitiveTriangle & other, GIM_TRIANGLE_CONTACT & contacts)
{
btScalar margin = m_margin + other.m_margin;
@@ -132,7 +132,7 @@ bool btPrimitiveTriangle::find_triangle_collision_clip_method(btPrimitiveTriangl
//create planes
// plane v vs U points
- BT_TRIANGLE_CONTACT contacts1;
+ GIM_TRIANGLE_CONTACT contacts1;
contacts1.m_separating_normal = m_plane;
@@ -152,7 +152,7 @@ bool btPrimitiveTriangle::find_triangle_collision_clip_method(btPrimitiveTriangl
//Clip tri1 by tri2 edges
- BT_TRIANGLE_CONTACT contacts2;
+ GIM_TRIANGLE_CONTACT contacts2;
contacts2.m_separating_normal = other.m_plane;
clipped_count = other.clip_triangle(*this,clipped_points);
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btTriangleShapeEx.h b/extern/bullet2/src/BulletCollision/Gimpact/btTriangleShapeEx.h
index bdaa323d564..bbd6b630c02 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btTriangleShapeEx.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btTriangleShapeEx.h
@@ -35,14 +35,14 @@ subject to the following restrictions:
#define MAX_TRI_CLIPPING 16
//! Structure for collision
-struct BT_TRIANGLE_CONTACT
+struct GIM_TRIANGLE_CONTACT
{
btScalar m_penetration_depth;
int m_point_count;
btVector4 m_separating_normal;
btVector3 m_points[MAX_TRI_CLIPPING];
- SIMD_FORCE_INLINE void copy_from(const BT_TRIANGLE_CONTACT& other)
+ SIMD_FORCE_INLINE void copy_from(const GIM_TRIANGLE_CONTACT& other)
{
m_penetration_depth = other.m_penetration_depth;
m_separating_normal = other.m_separating_normal;
@@ -54,11 +54,11 @@ struct BT_TRIANGLE_CONTACT
}
}
- BT_TRIANGLE_CONTACT()
+ GIM_TRIANGLE_CONTACT()
{
}
- BT_TRIANGLE_CONTACT(const BT_TRIANGLE_CONTACT& other)
+ GIM_TRIANGLE_CONTACT(const GIM_TRIANGLE_CONTACT& other)
{
copy_from(other);
}
@@ -123,7 +123,7 @@ public:
/*!
\pre this triangle and other must have their triangles calculated
*/
- bool find_triangle_collision_clip_method(btPrimitiveTriangle & other, BT_TRIANGLE_CONTACT & contacts);
+ bool find_triangle_collision_clip_method(btPrimitiveTriangle & other, GIM_TRIANGLE_CONTACT & contacts);
};
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_array.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_array.h
index 89fbb5ab0a5..c8161d252d5 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_array.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_array.h
@@ -34,11 +34,6 @@ email: projectileman@yahoo.com
#include "gim_memory.h"
-/*! \addtogroup CONTAINERS
-\brief
-Abstract class for template containers
-*/
-//! @{
#define GIM_ARRAY_GROW_INCREMENT 2
#define GIM_ARRAY_GROW_FACTOR 2
@@ -321,11 +316,10 @@ public:
{
resizeData(m_size);
}
-//!@}
+
};
-//! @}
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_basic_geometry_operations.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_basic_geometry_operations.h
index d4cbce04b5e..666abf7917a 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_basic_geometry_operations.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_basic_geometry_operations.h
@@ -40,9 +40,6 @@ email: projectileman@yahoo.com
-/*! \defgroup GEOMETRIC_OPERATIONS
-*/
-//! @{
#define PLANEDIREPSILON 0.0000001f
@@ -541,7 +538,6 @@ SIMD_FORCE_INLINE void SORT_3_INDICES(
-//! @}
#endif // GIM_VECTOR_H_INCLUDED
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_bitset.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_bitset.h
index 7784aeff140..322004a8d5b 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_bitset.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_bitset.h
@@ -34,11 +34,6 @@ email: projectileman@yahoo.com
#include "gim_array.h"
-/*! \addtogroup CONTAINERS
-\brief
-Abstract class for template containers
-*/
-//! @{
#define GUINT_BIT_COUNT 32
#define GUINT_EXPONENT 5
@@ -122,7 +117,6 @@ public:
};
-//! @}
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_box_collision.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_box_collision.h
index c9bb83e3653..0add5e4b99f 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_box_collision.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_box_collision.h
@@ -35,9 +35,6 @@ email: projectileman@yahoo.com
#include "gim_basic_geometry_operations.h"
#include "LinearMath/btTransform.h"
-/*! \defgroup BOUND_AABB_OPERATIONS
-*/
-//! @{
//SIMD_FORCE_INLINE bool test_cross_edge_box(
@@ -589,6 +586,5 @@ SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform & t1,const btT
}
-//! @}
#endif // GIM_BOX_COLLISION_H_INCLUDED
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_box_set.cpp b/extern/bullet2/src/BulletCollision/Gimpact/gim_box_set.cpp
index 1ffc2bbad78..0c3d7ba8db0 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_box_set.cpp
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_box_set.cpp
@@ -110,8 +110,7 @@ GUINT GIM_BOX_TREE::_sort_and_calc_splitting_index(
splitIndex = startIndex+ (numIndices>>1);
}
- bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex));
- btAssert(!unbal);
+ btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex))));
return splitIndex;
}
@@ -180,3 +179,4 @@ void GIM_BOX_TREE::build_tree(
_build_sub_tree(primitive_boxes, 0, primitive_boxes.size());
}
+
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_box_set.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_box_set.h
index ece5936de6b..1058a0872a5 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_box_set.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_box_set.h
@@ -40,12 +40,6 @@ email: projectileman@yahoo.com
#include "gim_tri_collision.h"
-/*! \defgroup BOX_PRUNNING
-
-
-
-*/
-//! @{
//! Overlapping pair
struct GIM_PAIR
@@ -446,7 +440,6 @@ public:
m_primitive_manager.get_primitive_triangle(getNodeData(nodeindex),triangle);
}
-//! @}
};
//! Class for Box Tree Sets
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_clip_polygon.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_clip_polygon.h
index 62151cb97b7..a91fd3aa422 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_clip_polygon.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_clip_polygon.h
@@ -33,9 +33,6 @@ email: projectileman@yahoo.com
-----------------------------------------------------------------------------
*/
-/*! \addtogroup GEOMETRIC_OPERATIONS
-*/
-//! @{
//! This function calcs the distance from a 3D plane
class DISTANCE_PLANE_3D_FUNC
@@ -209,6 +206,5 @@ SIMD_FORCE_INLINE GUINT PLANE_CLIP_TRIANGLE3D(
}
-//! @}
#endif // GIM_TRI_COLLISION_H_INCLUDED
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_contact.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_contact.h
index 62df51b782f..ad3e12298fe 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_contact.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_contact.h
@@ -36,17 +36,6 @@ email: projectileman@yahoo.com
#include "gim_radixsort.h"
#include "gim_array.h"
-/*! \defgroup CONTACTS
-\brief
-Functions for managing and sorting contacts resulting from a collision query.
-<ul>
-<li> Contact lists must be create by calling \ref GIM_CREATE_CONTACT_LIST
-<li> After querys, contact lists must be destroy by calling \ref GIM_DYNARRAY_DESTROY
-<li> Contacts can be merge for avoid duplicate results by calling \ref gim_merge_contacts
-</ul>
-
-*/
-//! @{
/**
Configuration var for applying interpolation of contact normals
@@ -55,6 +44,10 @@ Configuration var for applying interpolation of contact normals
#define CONTACT_DIFF_EPSILON 0.00001f
/// Structure for collision results
+///Functions for managing and sorting contacts resulting from a collision query.
+///Contact lists must be create by calling \ref GIM_CREATE_CONTACT_LIST
+///After querys, contact lists must be destroy by calling \ref GIM_DYNARRAY_DESTROY
+///Contacts can be merge for avoid duplicate results by calling \ref gim_merge_contacts
class GIM_CONTACT
{
public:
@@ -168,5 +161,4 @@ public:
void merge_contacts_unique(const gim_contact_array & contacts);
};
-//! @}
#endif // GIM_CONTACT_H_INCLUDED
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_geom_types.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_geom_types.h
index cd3e53dcc0c..2fb1e3f9e45 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_geom_types.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_geom_types.h
@@ -36,11 +36,7 @@ email: projectileman@yahoo.com
#include "gim_math.h"
-/*! \defgroup GEOMETRIC_TYPES
-\brief
-Basic types and constants for geometry
-*/
-//! @{
+
//! Short Integer vector 2D
typedef GSHORT vec2s[2];
@@ -95,7 +91,6 @@ typedef GREAL mat4f[4][4];
typedef GREAL quatf[4];
//typedef struct _aabb3f aabb3f;
-//! @}
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_hash_table.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_hash_table.h
index fd980dff5fa..93c66f81823 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_hash_table.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_hash_table.h
@@ -34,11 +34,6 @@ email: projectileman@yahoo.com
#include "gim_radixsort.h"
-/*! \addtogroup CONTAINERS
-\brief
-Abstract class for collision objects
-*/
-//! @{
#define GIM_INVALID_HASH 0xffffffff //!< A very very high value
#define GIM_DEFAULT_HASH_TABLE_SIZE 380
@@ -204,12 +199,7 @@ protected:
//SuperBufferedArray< _node_type > m_nodes;
bool m_sorted;
- /*! \defgroup HASH_TABLE_STRUCTURES
- \brief
- Hash table data management. The hash table has the indices to the corresponding m_nodes array
- */
- //! @{
-
+ ///Hash table data management. The hash table has the indices to the corresponding m_nodes array
GUINT * m_hash_table;//!<
GUINT m_table_size;//!<
GUINT m_node_size;//!<
@@ -459,13 +449,8 @@ protected:
}
- //! @}
-
- /*! \defgroup SORTED_ARRAY_STRUCTURES
- \brief
- Sorted array data management. The hash table has the indices to the corresponding m_nodes array
- */
- //! @{
+
+ ///Sorted array data management. The hash table has the indices to the corresponding m_nodes array
inline bool _erase_sorted(GUINT index)
{
if(index>=(GUINT)m_nodes.size()) return false;
@@ -575,8 +560,7 @@ protected:
return GIM_INVALID_HASH;
}
- //! @}
-
+
public:
@@ -913,8 +897,6 @@ public:
};
-//! @}
-
#endif // GIM_CONTAINERS_H_INCLUDED
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_linear_math.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_linear_math.h
index adf1c1c2ddf..0247d4e61cc 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_linear_math.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_linear_math.h
@@ -40,11 +40,6 @@ email: projectileman@yahoo.com
-/*! \defgroup VECTOR_OPERATIONS
-T
-Operations for vectors : vec2f,vec3f and vec4f
-*/
-//! @{
//! Zero out a 2D vector
#define VEC_ZERO_2(a) \
@@ -446,13 +441,8 @@ Takes two vectors a, b, blends them together with s <=1 */
-//! @}
-/*! \defgroup MATRIX_OPERATIONS
-Operations for matrices : mat2f, mat3f and mat4f
-*/
-//! @{
/// initialize matrix
#define IDENTIFY_MATRIX_3X3(m) \
@@ -1579,6 +1569,5 @@ and m is a mat4f<br>
}\
-//! @}
#endif // GIM_VECTOR_H_INCLUDED
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_math.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_math.h
index 25ad1e21c7f..8b9e6806ef7 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_math.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_math.h
@@ -35,13 +35,6 @@ email: projectileman@yahoo.com
#include "LinearMath/btScalar.h"
-/*! \defgroup BASIC_TYPES
-Basic types and constants
-Conventions:
-Types starting with G
-Constants starting with G_
-*/
-//! @{
#define GREAL btScalar
#define GREAL2 double
@@ -52,15 +45,7 @@ Constants starting with G_
#define GINT64 long long
#define GUINT64 unsigned long long
-//! @}
-/*! \defgroup BASIC_CONSTANTS
-Basic constants
-Conventions:
-Types starting with G
-Constants starting with G_
-*/
-//! @{
#define G_PI 3.14159265358979f
#define G_HALF_PI 1.5707963f
@@ -73,14 +58,9 @@ Constants starting with G_
#define G_REAL_INFINITY FLT_MAX
#define G_SIGN_BITMASK 0x80000000
#define G_EPSILON SIMD_EPSILON
-//! @}
-/*! \defgroup SCALAR_TYPES
-\brief
-Precision type constants
-*/
-//! @{
+
enum GIM_SCALAR_TYPES
{
G_STYPE_REAL =0,
@@ -92,12 +72,8 @@ enum GIM_SCALAR_TYPES
G_STYPE_INT64,
G_STYPE_UINT64
};
-//! @}
-/*! \defgroup MATH_FUNCTIONS
-mathematical functions
-*/
-//! @{
+
#define G_DEGTORAD(X) ((X)*3.1415926f/180.0f)
#define G_RADTODEG(X) ((X)*180.0f/3.1415926f)
@@ -131,7 +107,7 @@ mathematical functions
///returns a clamped number
#define GIM_CLAMP(number,minval,maxval) (number<minval?minval:(number>maxval?maxval:number))
-#define GIM_GREATER(x, y) fabsf(x) > (y)
+#define GIM_GREATER(x, y) btFabs(x) > (y)
///Swap numbers
#define GIM_SWAP_NUMBERS(a,b){ \
@@ -176,6 +152,6 @@ inline GREAL gim_sqrt(GREAL f)
return r;
}
-//! @}
+
#endif // GIM_MATH_H_INCLUDED
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_memory.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_memory.h
index 469a8280f7d..fa99eebb60e 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_memory.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_memory.h
@@ -36,9 +36,6 @@ email: projectileman@yahoo.com
#include "gim_math.h"
#include <memory.h>
-//#define PREFETCH 1
-//! \defgroup PREFETCH
-//! @{
#ifdef PREFETCH
#include <xmmintrin.h> // for prefetch
#define pfval 64
@@ -53,13 +50,9 @@ email: projectileman@yahoo.com
//! Prefetch 128
#define pf2(_x,_i)
#endif
-//! @}
-/*! \defgroup ARRAY_UTILITIES
-\brief
-Functions for manip packed arrays of numbers
-*/
-//! @{
+
+///Functions for manip packed arrays of numbers
#define GIM_COPY_ARRAYS(dest_array,source_array,element_count)\
{\
for (GUINT _i_=0;_i_<element_count ;++_i_)\
@@ -92,50 +85,36 @@ Functions for manip packed arrays of numbers
array[_i_] = constant;\
}\
}\
-//! @}
-/*! \defgroup MEMORY_FUNCTION_PROTOTYPES
-Function prototypes to allocate and free memory.
-*/
-//! @{
+
+///Function prototypes to allocate and free memory.
typedef void * gim_alloc_function (size_t size);
typedef void * gim_alloca_function (size_t size);//Allocs on the heap
typedef void * gim_realloc_function (void *ptr, size_t oldsize, size_t newsize);
typedef void gim_free_function (void *ptr);
-//! @}
-
-/*! \defgroup MEMORY_FUNCTION_HANDLERS
-\brief
-Memory Function Handlers
- set new memory management functions. if fn is 0, the default handlers are
- used. */
-//! @{
+
+
+///Memory Function Handlers
+///set new memory management functions. if fn is 0, the default handlers are used.
void gim_set_alloc_handler (gim_alloc_function *fn);
void gim_set_alloca_handler (gim_alloca_function *fn);
void gim_set_realloc_handler (gim_realloc_function *fn);
void gim_set_free_handler (gim_free_function *fn);
-//! @}
-/*! \defgroup MEMORY_FUNCTION_GET_HANDLERS
-\brief
-get current memory management functions.
-*/
-//! @{
+
+///get current memory management functions.
gim_alloc_function *gim_get_alloc_handler (void);
gim_alloca_function *gim_get_alloca_handler(void);
gim_realloc_function *gim_get_realloc_handler (void);
gim_free_function *gim_get_free_handler (void);
-//! @}
-/*! \defgroup MEMORY_FUNCTIONS
-Standar Memory functions
-*/
-//! @{
+
+///Standar Memory functions
void * gim_alloc(size_t size);
void * gim_alloca(size_t size);
void * gim_realloc(void *ptr, size_t oldsize, size_t newsize);
void gim_free(void *ptr);
-//! @}
+
#if defined (WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_radixsort.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_radixsort.h
index 9ecf61bdc6d..f7dadbbca93 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_radixsort.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_radixsort.h
@@ -36,11 +36,7 @@ email: projectileman@yahoo.com
#include "gim_memory.h"
-/*! \defgroup SORTING
-\brief
-Macros for sorting.
-*/
-
+///Macros for sorting.
//! Prototype for comparators
class less_comparator
{
@@ -406,5 +402,5 @@ void gim_heap_sort(T *pArr, GUINT element_count, COMP_CLASS CompareFunc)
-//! @}
+
#endif // GIM_RADIXSORT_H_INCLUDED
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_tri_collision.cpp b/extern/bullet2/src/BulletCollision/Gimpact/gim_tri_collision.cpp
index ef6feabdfee..74d734146a7 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_tri_collision.cpp
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_tri_collision.cpp
@@ -38,7 +38,7 @@ email: projectileman@yahoo.com
#define MIN_EDGE_EDGE_DIS 0.00001f
-class _GIM_TRIANGLE_CALCULATION_CACHE
+class GIM_TRIANGLE_CALCULATION_CACHE
{
public:
GREAL margin;
@@ -489,7 +489,7 @@ public:
};
-/*class _GIM_TRIANGLE_CALCULATION_CACHE
+/*class GIM_TRIANGLE_CALCULATION_CACHE
{
public:
GREAL margin;
@@ -627,7 +627,7 @@ bool GIM_TRIANGLE::collide_triangle_hard_test(
const GIM_TRIANGLE & other,
GIM_TRIANGLE_CONTACT_DATA & contact_data) const
{
- _GIM_TRIANGLE_CALCULATION_CACHE calc_cache;
+ GIM_TRIANGLE_CALCULATION_CACHE calc_cache;
return calc_cache.triangle_collision(
m_vertices[0],m_vertices[1],m_vertices[2],m_margin,
other.m_vertices[0],other.m_vertices[1],other.m_vertices[2],other.m_margin,
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_tri_collision.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_tri_collision.h
index 7cea8fc33a6..2d6e43a1a2e 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_tri_collision.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_tri_collision.h
@@ -36,9 +36,6 @@ email: projectileman@yahoo.com
#include "gim_box_collision.h"
#include "gim_clip_polygon.h"
-/*! \addtogroup GEOMETRIC_OPERATIONS
-*/
-//! @{
@@ -278,7 +275,7 @@ if 0.0<= u+v <=1.0 then they are inside of triangle
}
else
{
- float sumuv;
+ btScalar sumuv;
sumuv = u+v;
if(sumuv<-G_EPSILON)
{
@@ -378,6 +375,5 @@ if 0.0<= u+v <=1.0 then they are inside of triangle
-//! @}
#endif // GIM_TRI_COLLISION_H_INCLUDED
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
index 6551cfb92fe..2f41b3c2757 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
@@ -135,6 +135,9 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
//btScalar clippedDist = GEN_min(angularConservativeRadius,dist);
//btScalar clippedDist = dist;
+ //don't report time of impact for motion away from the contact normal (or causes minor penetration)
+ if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=SIMD_EPSILON)
+ return false;
dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity);
@@ -196,11 +199,10 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
}
}
-
- //don't report time of impact for motion away from the contact normal (or causes minor penetration)
+
if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=result.m_allowedPenetration)//SIMD_EPSILON)
return false;
-
+
result.m_fraction = lambda;
result.m_normal = n;
result.m_hitPoint = c;
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
index 99690921317..412aace2114 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
@@ -21,7 +21,6 @@ class btStackAlloc;
class btVector3;
#include "btSimplexSolverInterface.h"
class btConvexShape;
-#include "LinearMath/btPoint3.h"
class btTransform;
///ConvexPenetrationDepthSolver provides an interface for penetration depth calculation.
@@ -33,7 +32,7 @@ public:
virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver,
const btConvexShape* convexA,const btConvexShape* convexB,
const btTransform& transA,const btTransform& transB,
- btVector3& v, btPoint3& pa, btPoint3& pb,
+ btVector3& v, btVector3& pa, btVector3& pb,
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
) = 0;
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp
index ccfc22ee673..ada20d3ef7a 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp
@@ -37,7 +37,7 @@ GJK-EPA collision solver by Nathanael Presson, 2008
namespace gjkepa2_impl
{
-// Config
+ // Config
/* GJK */
#define GJK_MAX_ITERATIONS 128
@@ -58,711 +58,711 @@ namespace gjkepa2_impl
#define EPA_INSIDE_EPS ((btScalar)0.01)
-// Shorthands
-typedef unsigned int U;
-typedef unsigned char U1;
+ // Shorthands
+ typedef unsigned int U;
+ typedef unsigned char U1;
-// MinkowskiDiff
-struct MinkowskiDiff
+ // MinkowskiDiff
+ struct MinkowskiDiff
{
- const btConvexShape* m_shapes[2];
- btMatrix3x3 m_toshape1;
- btTransform m_toshape0;
- btVector3 (btConvexShape::*Ls)(const btVector3&) const;
- void EnableMargin(bool enable)
+ const btConvexShape* m_shapes[2];
+ btMatrix3x3 m_toshape1;
+ btTransform m_toshape0;
+ btVector3 (btConvexShape::*Ls)(const btVector3&) const;
+ void EnableMargin(bool enable)
{
- if(enable)
- Ls=&btConvexShape::localGetSupportingVertex;
+ if(enable)
+ Ls=&btConvexShape::localGetSupportVertexNonVirtual;
else
- Ls=&btConvexShape::localGetSupportingVertexWithoutMargin;
+ Ls=&btConvexShape::localGetSupportVertexWithoutMarginNonVirtual;
}
- inline btVector3 Support0(const btVector3& d) const
+ inline btVector3 Support0(const btVector3& d) const
{
- return(((m_shapes[0])->*(Ls))(d));
+ return(((m_shapes[0])->*(Ls))(d));
}
- inline btVector3 Support1(const btVector3& d) const
+ inline btVector3 Support1(const btVector3& d) const
{
- return(m_toshape0*((m_shapes[1])->*(Ls))(m_toshape1*d));
+ return(m_toshape0*((m_shapes[1])->*(Ls))(m_toshape1*d));
}
- inline btVector3 Support(const btVector3& d) const
+ inline btVector3 Support(const btVector3& d) const
{
- return(Support0(d)-Support1(-d));
+ return(Support0(d)-Support1(-d));
}
- btVector3 Support(const btVector3& d,U index) const
+ btVector3 Support(const btVector3& d,U index) const
{
- if(index)
- return(Support1(d));
+ if(index)
+ return(Support1(d));
else
- return(Support0(d));
+ return(Support0(d));
}
};
-typedef MinkowskiDiff tShape;
+ typedef MinkowskiDiff tShape;
-// GJK
-struct GJK
-{
-/* Types */
-struct sSV
- {
- btVector3 d,w;
- };
-struct sSimplex
- {
- sSV* c[4];
- btScalar p[4];
- U rank;
- };
-struct eStatus { enum _ {
- Valid,
- Inside,
- Failed };};
-/* Fields */
-tShape m_shape;
-btVector3 m_ray;
-btScalar m_distance;
-sSimplex m_simplices[2];
-sSV m_store[4];
-sSV* m_free[4];
-U m_nfree;
-U m_current;
-sSimplex* m_simplex;
-eStatus::_ m_status;
-/* Methods */
- GJK()
- {
- Initialize();
- }
-void Initialize()
+ // GJK
+ struct GJK
{
- m_ray = btVector3(0,0,0);
- m_nfree = 0;
- m_status = eStatus::Failed;
- m_current = 0;
- m_distance = 0;
- }
-eStatus::_ Evaluate(const tShape& shapearg,const btVector3& guess)
- {
- U iterations=0;
- btScalar sqdist=0;
- btScalar alpha=0;
- btVector3 lastw[4];
- U clastw=0;
- /* Initialize solver */
- m_free[0] = &m_store[0];
- m_free[1] = &m_store[1];
- m_free[2] = &m_store[2];
- m_free[3] = &m_store[3];
- m_nfree = 4;
- m_current = 0;
- m_status = eStatus::Valid;
- m_shape = shapearg;
- m_distance = 0;
- /* Initialize simplex */
- m_simplices[0].rank = 0;
- m_ray = guess;
- const btScalar sqrl= m_ray.length2();
- appendvertice(m_simplices[0],sqrl>0?-m_ray:btVector3(1,0,0));
- m_simplices[0].p[0] = 1;
- m_ray = m_simplices[0].c[0]->w;
- sqdist = sqrl;
- lastw[0] =
- lastw[1] =
- lastw[2] =
- lastw[3] = m_ray;
- /* Loop */
- do {
- const U next=1-m_current;
- sSimplex& cs=m_simplices[m_current];
- sSimplex& ns=m_simplices[next];
- /* Check zero */
- const btScalar rl=m_ray.length();
- if(rl<GJK_MIN_DISTANCE)
- {/* Touching or inside */
- m_status=eStatus::Inside;
- break;
- }
- /* Append new vertice in -'v' direction */
- appendvertice(cs,-m_ray);
- const btVector3& w=cs.c[cs.rank-1]->w;
- bool found=false;
- for(U i=0;i<4;++i)
+ /* Types */
+ struct sSV
+ {
+ btVector3 d,w;
+ };
+ struct sSimplex
+ {
+ sSV* c[4];
+ btScalar p[4];
+ U rank;
+ };
+ struct eStatus { enum _ {
+ Valid,
+ Inside,
+ Failed };};
+ /* Fields */
+ tShape m_shape;
+ btVector3 m_ray;
+ btScalar m_distance;
+ sSimplex m_simplices[2];
+ sSV m_store[4];
+ sSV* m_free[4];
+ U m_nfree;
+ U m_current;
+ sSimplex* m_simplex;
+ eStatus::_ m_status;
+ /* Methods */
+ GJK()
{
- if((w-lastw[i]).length2()<GJK_DUPLICATED_EPS)
- { found=true;break; }
- }
- if(found)
- {/* Return old simplex */
- removevertice(m_simplices[m_current]);
- break;
+ Initialize();
}
- else
- {/* Update lastw */
- lastw[clastw=(clastw+1)&3]=w;
- }
- /* Check for termination */
- const btScalar omega=dot(m_ray,w)/rl;
- alpha=btMax(omega,alpha);
- if(((rl-alpha)-(GJK_ACCURARY*rl))<=0)
- {/* Return old simplex */
- removevertice(m_simplices[m_current]);
- break;
- }
- /* Reduce simplex */
- btScalar weights[4];
- U mask=0;
- switch(cs.rank)
+ void Initialize()
{
- case 2: sqdist=projectorigin( cs.c[0]->w,
- cs.c[1]->w,
- weights,mask);break;
- case 3: sqdist=projectorigin( cs.c[0]->w,
- cs.c[1]->w,
- cs.c[2]->w,
- weights,mask);break;
- case 4: sqdist=projectorigin( cs.c[0]->w,
- cs.c[1]->w,
- cs.c[2]->w,
- cs.c[3]->w,
- weights,mask);break;
+ m_ray = btVector3(0,0,0);
+ m_nfree = 0;
+ m_status = eStatus::Failed;
+ m_current = 0;
+ m_distance = 0;
}
- if(sqdist>=0)
- {/* Valid */
- ns.rank = 0;
- m_ray = btVector3(0,0,0);
- m_current = next;
- for(U i=0,ni=cs.rank;i<ni;++i)
- {
- if(mask&(1<<i))
+ eStatus::_ Evaluate(const tShape& shapearg,const btVector3& guess)
+ {
+ U iterations=0;
+ btScalar sqdist=0;
+ btScalar alpha=0;
+ btVector3 lastw[4];
+ U clastw=0;
+ /* Initialize solver */
+ m_free[0] = &m_store[0];
+ m_free[1] = &m_store[1];
+ m_free[2] = &m_store[2];
+ m_free[3] = &m_store[3];
+ m_nfree = 4;
+ m_current = 0;
+ m_status = eStatus::Valid;
+ m_shape = shapearg;
+ m_distance = 0;
+ /* Initialize simplex */
+ m_simplices[0].rank = 0;
+ m_ray = guess;
+ const btScalar sqrl= m_ray.length2();
+ appendvertice(m_simplices[0],sqrl>0?-m_ray:btVector3(1,0,0));
+ m_simplices[0].p[0] = 1;
+ m_ray = m_simplices[0].c[0]->w;
+ sqdist = sqrl;
+ lastw[0] =
+ lastw[1] =
+ lastw[2] =
+ lastw[3] = m_ray;
+ /* Loop */
+ do {
+ const U next=1-m_current;
+ sSimplex& cs=m_simplices[m_current];
+ sSimplex& ns=m_simplices[next];
+ /* Check zero */
+ const btScalar rl=m_ray.length();
+ if(rl<GJK_MIN_DISTANCE)
+ {/* Touching or inside */
+ m_status=eStatus::Inside;
+ break;
+ }
+ /* Append new vertice in -'v' direction */
+ appendvertice(cs,-m_ray);
+ const btVector3& w=cs.c[cs.rank-1]->w;
+ bool found=false;
+ for(U i=0;i<4;++i)
{
- ns.c[ns.rank] = cs.c[i];
- ns.p[ns.rank++] = weights[i];
- m_ray += cs.c[i]->w*weights[i];
+ if((w-lastw[i]).length2()<GJK_DUPLICATED_EPS)
+ { found=true;break; }
+ }
+ if(found)
+ {/* Return old simplex */
+ removevertice(m_simplices[m_current]);
+ break;
}
else
+ {/* Update lastw */
+ lastw[clastw=(clastw+1)&3]=w;
+ }
+ /* Check for termination */
+ const btScalar omega=dot(m_ray,w)/rl;
+ alpha=btMax(omega,alpha);
+ if(((rl-alpha)-(GJK_ACCURARY*rl))<=0)
+ {/* Return old simplex */
+ removevertice(m_simplices[m_current]);
+ break;
+ }
+ /* Reduce simplex */
+ btScalar weights[4];
+ U mask=0;
+ switch(cs.rank)
{
- m_free[m_nfree++] = cs.c[i];
+ case 2: sqdist=projectorigin( cs.c[0]->w,
+ cs.c[1]->w,
+ weights,mask);break;
+ case 3: sqdist=projectorigin( cs.c[0]->w,
+ cs.c[1]->w,
+ cs.c[2]->w,
+ weights,mask);break;
+ case 4: sqdist=projectorigin( cs.c[0]->w,
+ cs.c[1]->w,
+ cs.c[2]->w,
+ cs.c[3]->w,
+ weights,mask);break;
}
- }
- if(mask==15) m_status=eStatus::Inside;
- }
- else
- {/* Return old simplex */
- removevertice(m_simplices[m_current]);
- break;
- }
- m_status=((++iterations)<GJK_MAX_ITERATIONS)?m_status:eStatus::Failed;
- } while(m_status==eStatus::Valid);
- m_simplex=&m_simplices[m_current];
- switch(m_status)
- {
- case eStatus::Valid: m_distance=m_ray.length();break;
- case eStatus::Inside: m_distance=0;break;
- }
- return(m_status);
- }
-bool EncloseOrigin()
- {
- switch(m_simplex->rank)
- {
- case 1:
- {
- for(U i=0;i<3;++i)
+ if(sqdist>=0)
+ {/* Valid */
+ ns.rank = 0;
+ m_ray = btVector3(0,0,0);
+ m_current = next;
+ for(U i=0,ni=cs.rank;i<ni;++i)
+ {
+ if(mask&(1<<i))
+ {
+ ns.c[ns.rank] = cs.c[i];
+ ns.p[ns.rank++] = weights[i];
+ m_ray += cs.c[i]->w*weights[i];
+ }
+ else
+ {
+ m_free[m_nfree++] = cs.c[i];
+ }
+ }
+ if(mask==15) m_status=eStatus::Inside;
+ }
+ else
+ {/* Return old simplex */
+ removevertice(m_simplices[m_current]);
+ break;
+ }
+ m_status=((++iterations)<GJK_MAX_ITERATIONS)?m_status:eStatus::Failed;
+ } while(m_status==eStatus::Valid);
+ m_simplex=&m_simplices[m_current];
+ switch(m_status)
{
- btVector3 axis=btVector3(0,0,0);
- axis[i]=1;
- appendvertice(*m_simplex, axis);
- if(EncloseOrigin()) return(true);
- removevertice(*m_simplex);
- appendvertice(*m_simplex,-axis);
- if(EncloseOrigin()) return(true);
- removevertice(*m_simplex);
- }
+ case eStatus::Valid: m_distance=m_ray.length();break;
+ case eStatus::Inside: m_distance=0;break;
+ }
+ return(m_status);
}
- break;
- case 2:
+ bool EncloseOrigin()
{
- const btVector3 d=m_simplex->c[1]->w-m_simplex->c[0]->w;
- for(U i=0;i<3;++i)
+ switch(m_simplex->rank)
{
- btVector3 axis=btVector3(0,0,0);
- axis[i]=1;
- const btVector3 p=cross(d,axis);
- if(p.length2()>0)
+ case 1:
+ {
+ for(U i=0;i<3;++i)
+ {
+ btVector3 axis=btVector3(0,0,0);
+ axis[i]=1;
+ appendvertice(*m_simplex, axis);
+ if(EncloseOrigin()) return(true);
+ removevertice(*m_simplex);
+ appendvertice(*m_simplex,-axis);
+ if(EncloseOrigin()) return(true);
+ removevertice(*m_simplex);
+ }
+ }
+ break;
+ case 2:
+ {
+ const btVector3 d=m_simplex->c[1]->w-m_simplex->c[0]->w;
+ for(U i=0;i<3;++i)
+ {
+ btVector3 axis=btVector3(0,0,0);
+ axis[i]=1;
+ const btVector3 p=cross(d,axis);
+ if(p.length2()>0)
+ {
+ appendvertice(*m_simplex, p);
+ if(EncloseOrigin()) return(true);
+ removevertice(*m_simplex);
+ appendvertice(*m_simplex,-p);
+ if(EncloseOrigin()) return(true);
+ removevertice(*m_simplex);
+ }
+ }
+ }
+ break;
+ case 3:
+ {
+ const btVector3 n=cross(m_simplex->c[1]->w-m_simplex->c[0]->w,
+ m_simplex->c[2]->w-m_simplex->c[0]->w);
+ if(n.length2()>0)
+ {
+ appendvertice(*m_simplex,n);
+ if(EncloseOrigin()) return(true);
+ removevertice(*m_simplex);
+ appendvertice(*m_simplex,-n);
+ if(EncloseOrigin()) return(true);
+ removevertice(*m_simplex);
+ }
+ }
+ break;
+ case 4:
{
- appendvertice(*m_simplex, p);
- if(EncloseOrigin()) return(true);
- removevertice(*m_simplex);
- appendvertice(*m_simplex,-p);
- if(EncloseOrigin()) return(true);
- removevertice(*m_simplex);
+ if(btFabs(det( m_simplex->c[0]->w-m_simplex->c[3]->w,
+ m_simplex->c[1]->w-m_simplex->c[3]->w,
+ m_simplex->c[2]->w-m_simplex->c[3]->w))>0)
+ return(true);
}
+ break;
}
+ return(false);
}
- break;
- case 3:
+ /* Internals */
+ void getsupport(const btVector3& d,sSV& sv) const
{
- const btVector3 n=cross(m_simplex->c[1]->w-m_simplex->c[0]->w,
- m_simplex->c[2]->w-m_simplex->c[0]->w);
- if(n.length2()>0)
- {
- appendvertice(*m_simplex,n);
- if(EncloseOrigin()) return(true);
- removevertice(*m_simplex);
- appendvertice(*m_simplex,-n);
- if(EncloseOrigin()) return(true);
- removevertice(*m_simplex);
- }
+ sv.d = d/d.length();
+ sv.w = m_shape.Support(sv.d);
}
- break;
- case 4:
+ void removevertice(sSimplex& simplex)
{
- if(btFabs(det( m_simplex->c[0]->w-m_simplex->c[3]->w,
- m_simplex->c[1]->w-m_simplex->c[3]->w,
- m_simplex->c[2]->w-m_simplex->c[3]->w))>0)
- return(true);
+ m_free[m_nfree++]=simplex.c[--simplex.rank];
}
- break;
- }
- return(false);
- }
-/* Internals */
-void getsupport(const btVector3& d,sSV& sv) const
- {
- sv.d = d/d.length();
- sv.w = m_shape.Support(sv.d);
- }
-void removevertice(sSimplex& simplex)
- {
- m_free[m_nfree++]=simplex.c[--simplex.rank];
- }
-void appendvertice(sSimplex& simplex,const btVector3& v)
- {
- simplex.p[simplex.rank]=0;
- simplex.c[simplex.rank]=m_free[--m_nfree];
- getsupport(v,*simplex.c[simplex.rank++]);
- }
-static btScalar det(const btVector3& a,const btVector3& b,const btVector3& c)
- {
- return( a.y()*b.z()*c.x()+a.z()*b.x()*c.y()-
- a.x()*b.z()*c.y()-a.y()*b.x()*c.z()+
- a.x()*b.y()*c.z()-a.z()*b.y()*c.x());
- }
-static btScalar projectorigin( const btVector3& a,
- const btVector3& b,
- btScalar* w,U& m)
- {
- const btVector3 d=b-a;
- const btScalar l=d.length2();
- if(l>GJK_SIMPLEX2_EPS)
- {
- const btScalar t(l>0?-dot(a,d)/l:0);
- if(t>=1) { w[0]=0;w[1]=1;m=2;return(b.length2()); }
- else if(t<=0) { w[0]=1;w[1]=0;m=1;return(a.length2()); }
- else { w[0]=1-(w[1]=t);m=3;return((a+d*t).length2()); }
- }
- return(-1);
- }
-static btScalar projectorigin( const btVector3& a,
- const btVector3& b,
- const btVector3& c,
- btScalar* w,U& m)
- {
- static const U imd3[]={1,2,0};
- const btVector3* vt[]={&a,&b,&c};
- const btVector3 dl[]={a-b,b-c,c-a};
- const btVector3 n=cross(dl[0],dl[1]);
- const btScalar l=n.length2();
- if(l>GJK_SIMPLEX3_EPS)
- {
- btScalar mindist=-1;
- btScalar subw[2];
- U subm;
- for(U i=0;i<3;++i)
+ void appendvertice(sSimplex& simplex,const btVector3& v)
+ {
+ simplex.p[simplex.rank]=0;
+ simplex.c[simplex.rank]=m_free[--m_nfree];
+ getsupport(v,*simplex.c[simplex.rank++]);
+ }
+ static btScalar det(const btVector3& a,const btVector3& b,const btVector3& c)
{
- if(dot(*vt[i],cross(dl[i],n))>0)
+ return( a.y()*b.z()*c.x()+a.z()*b.x()*c.y()-
+ a.x()*b.z()*c.y()-a.y()*b.x()*c.z()+
+ a.x()*b.y()*c.z()-a.z()*b.y()*c.x());
+ }
+ static btScalar projectorigin( const btVector3& a,
+ const btVector3& b,
+ btScalar* w,U& m)
+ {
+ const btVector3 d=b-a;
+ const btScalar l=d.length2();
+ if(l>GJK_SIMPLEX2_EPS)
{
- const U j=imd3[i];
- const btScalar subd(projectorigin(*vt[i],*vt[j],subw,subm));
- if((mindist<0)||(subd<mindist))
- {
- mindist = subd;
- m = static_cast<U>(((subm&1)?1<<i:0)+((subm&2)?1<<j:0));
- w[i] = subw[0];
- w[j] = subw[1];
- w[imd3[j]] = 0;
- }
+ const btScalar t(l>0?-dot(a,d)/l:0);
+ if(t>=1) { w[0]=0;w[1]=1;m=2;return(b.length2()); }
+ else if(t<=0) { w[0]=1;w[1]=0;m=1;return(a.length2()); }
+ else { w[0]=1-(w[1]=t);m=3;return((a+d*t).length2()); }
}
+ return(-1);
}
- if(mindist<0)
+ static btScalar projectorigin( const btVector3& a,
+ const btVector3& b,
+ const btVector3& c,
+ btScalar* w,U& m)
{
- const btScalar d=dot(a,n);
- const btScalar s=btSqrt(l);
- const btVector3 p=n*(d/l);
- mindist = p.length2();
- m = 7;
- w[0] = (cross(dl[1],b-p)).length()/s;
- w[1] = (cross(dl[2],c-p)).length()/s;
- w[2] = 1-(w[0]+w[1]);
+ static const U imd3[]={1,2,0};
+ const btVector3* vt[]={&a,&b,&c};
+ const btVector3 dl[]={a-b,b-c,c-a};
+ const btVector3 n=cross(dl[0],dl[1]);
+ const btScalar l=n.length2();
+ if(l>GJK_SIMPLEX3_EPS)
+ {
+ btScalar mindist=-1;
+ btScalar subw[2];
+ U subm;
+ for(U i=0;i<3;++i)
+ {
+ if(dot(*vt[i],cross(dl[i],n))>0)
+ {
+ const U j=imd3[i];
+ const btScalar subd(projectorigin(*vt[i],*vt[j],subw,subm));
+ if((mindist<0)||(subd<mindist))
+ {
+ mindist = subd;
+ m = static_cast<U>(((subm&1)?1<<i:0)+((subm&2)?1<<j:0));
+ w[i] = subw[0];
+ w[j] = subw[1];
+ w[imd3[j]] = 0;
+ }
+ }
+ }
+ if(mindist<0)
+ {
+ const btScalar d=dot(a,n);
+ const btScalar s=btSqrt(l);
+ const btVector3 p=n*(d/l);
+ mindist = p.length2();
+ m = 7;
+ w[0] = (cross(dl[1],b-p)).length()/s;
+ w[1] = (cross(dl[2],c-p)).length()/s;
+ w[2] = 1-(w[0]+w[1]);
+ }
+ return(mindist);
+ }
+ return(-1);
}
- return(mindist);
- }
- return(-1);
- }
-static btScalar projectorigin( const btVector3& a,
- const btVector3& b,
- const btVector3& c,
- const btVector3& d,
- btScalar* w,U& m)
- {
- static const U imd3[]={1,2,0};
- const btVector3* vt[]={&a,&b,&c,&d};
- const btVector3 dl[]={a-d,b-d,c-d};
- const btScalar vl=det(dl[0],dl[1],dl[2]);
- const bool ng=(vl*dot(a,cross(b-c,a-b)))<=0;
- if(ng&&(btFabs(vl)>GJK_SIMPLEX4_EPS))
- {
- btScalar mindist=-1;
- btScalar subw[3];
- U subm;
- for(U i=0;i<3;++i)
+ static btScalar projectorigin( const btVector3& a,
+ const btVector3& b,
+ const btVector3& c,
+ const btVector3& d,
+ btScalar* w,U& m)
{
- const U j=imd3[i];
- const btScalar s=vl*dot(d,cross(dl[i],dl[j]));
- if(s>0)
+ static const U imd3[]={1,2,0};
+ const btVector3* vt[]={&a,&b,&c,&d};
+ const btVector3 dl[]={a-d,b-d,c-d};
+ const btScalar vl=det(dl[0],dl[1],dl[2]);
+ const bool ng=(vl*dot(a,cross(b-c,a-b)))<=0;
+ if(ng&&(btFabs(vl)>GJK_SIMPLEX4_EPS))
{
- const btScalar subd=projectorigin(*vt[i],*vt[j],d,subw,subm);
- if((mindist<0)||(subd<mindist))
+ btScalar mindist=-1;
+ btScalar subw[3];
+ U subm;
+ for(U i=0;i<3;++i)
{
- mindist = subd;
- m = static_cast<U>((subm&1?1<<i:0)+
+ const U j=imd3[i];
+ const btScalar s=vl*dot(d,cross(dl[i],dl[j]));
+ if(s>0)
+ {
+ const btScalar subd=projectorigin(*vt[i],*vt[j],d,subw,subm);
+ if((mindist<0)||(subd<mindist))
+ {
+ mindist = subd;
+ m = static_cast<U>((subm&1?1<<i:0)+
(subm&2?1<<j:0)+
(subm&4?8:0));
- w[i] = subw[0];
- w[j] = subw[1];
- w[imd3[j]] = 0;
- w[3] = subw[2];
+ w[i] = subw[0];
+ w[j] = subw[1];
+ w[imd3[j]] = 0;
+ w[3] = subw[2];
+ }
+ }
+ }
+ if(mindist<0)
+ {
+ mindist = 0;
+ m = 15;
+ w[0] = det(c,b,d)/vl;
+ w[1] = det(a,c,d)/vl;
+ w[2] = det(b,a,d)/vl;
+ w[3] = 1-(w[0]+w[1]+w[2]);
}
+ return(mindist);
}
+ return(-1);
}
- if(mindist<0)
- {
- mindist = 0;
- m = 15;
- w[0] = det(c,b,d)/vl;
- w[1] = det(a,c,d)/vl;
- w[2] = det(b,a,d)/vl;
- w[3] = 1-(w[0]+w[1]+w[2]);
- }
- return(mindist);
- }
- return(-1);
- }
-};
-
-// EPA
-struct EPA
-{
-/* Types */
-typedef GJK::sSV sSV;
-struct sFace
- {
- btVector3 n;
- btScalar d;
- btScalar p;
- sSV* c[3];
- sFace* f[3];
- sFace* l[2];
- U1 e[3];
- U1 pass;
};
-struct sList
- {
- sFace* root;
- U count;
- sList() : root(0),count(0) {}
- };
-struct sHorizon
- {
- sFace* cf;
- sFace* ff;
- U nf;
- sHorizon() : cf(0),ff(0),nf(0) {}
- };
-struct eStatus { enum _ {
- Valid,
- Touching,
- Degenerated,
- NonConvex,
- InvalidHull,
- OutOfFaces,
- OutOfVertices,
- AccuraryReached,
- FallBack,
- Failed };};
-/* Fields */
-eStatus::_ m_status;
-GJK::sSimplex m_result;
-btVector3 m_normal;
-btScalar m_depth;
-sSV m_sv_store[EPA_MAX_VERTICES];
-sFace m_fc_store[EPA_MAX_FACES];
-U m_nextsv;
-sList m_hull;
-sList m_stock;
-/* Methods */
- EPA()
- {
- Initialize();
- }
-
- static inline void bind(sFace* fa,U ea,sFace* fb,U eb)
- {
- fa->e[ea]=(U1)eb;fa->f[ea]=fb;
- fb->e[eb]=(U1)ea;fb->f[eb]=fa;
- }
-static inline void append(sList& list,sFace* face)
+ // EPA
+ struct EPA
{
- face->l[0] = 0;
- face->l[1] = list.root;
- if(list.root) list.root->l[0]=face;
- list.root = face;
- ++list.count;
- }
-static inline void remove(sList& list,sFace* face)
- {
- if(face->l[1]) face->l[1]->l[0]=face->l[0];
- if(face->l[0]) face->l[0]->l[1]=face->l[1];
- if(face==list.root) list.root=face->l[1];
- --list.count;
- }
-
-
-void Initialize()
- {
- m_status = eStatus::Failed;
- m_normal = btVector3(0,0,0);
- m_depth = 0;
- m_nextsv = 0;
- for(U i=0;i<EPA_MAX_FACES;++i)
+ /* Types */
+ typedef GJK::sSV sSV;
+ struct sFace
{
- append(m_stock,&m_fc_store[EPA_MAX_FACES-i-1]);
- }
- }
-eStatus::_ Evaluate(GJK& gjk,const btVector3& guess)
- {
- GJK::sSimplex& simplex=*gjk.m_simplex;
- if((simplex.rank>1)&&gjk.EncloseOrigin())
+ btVector3 n;
+ btScalar d;
+ btScalar p;
+ sSV* c[3];
+ sFace* f[3];
+ sFace* l[2];
+ U1 e[3];
+ U1 pass;
+ };
+ struct sList
+ {
+ sFace* root;
+ U count;
+ sList() : root(0),count(0) {}
+ };
+ struct sHorizon
{
+ sFace* cf;
+ sFace* ff;
+ U nf;
+ sHorizon() : cf(0),ff(0),nf(0) {}
+ };
+ struct eStatus { enum _ {
+ Valid,
+ Touching,
+ Degenerated,
+ NonConvex,
+ InvalidHull,
+ OutOfFaces,
+ OutOfVertices,
+ AccuraryReached,
+ FallBack,
+ Failed };};
+ /* Fields */
+ eStatus::_ m_status;
+ GJK::sSimplex m_result;
+ btVector3 m_normal;
+ btScalar m_depth;
+ sSV m_sv_store[EPA_MAX_VERTICES];
+ sFace m_fc_store[EPA_MAX_FACES];
+ U m_nextsv;
+ sList m_hull;
+ sList m_stock;
+ /* Methods */
+ EPA()
+ {
+ Initialize();
+ }
- /* Clean up */
- while(m_hull.root)
+
+ static inline void bind(sFace* fa,U ea,sFace* fb,U eb)
{
- sFace* f = m_hull.root;
- remove(m_hull,f);
- append(m_stock,f);
+ fa->e[ea]=(U1)eb;fa->f[ea]=fb;
+ fb->e[eb]=(U1)ea;fb->f[eb]=fa;
}
- m_status = eStatus::Valid;
- m_nextsv = 0;
- /* Orient simplex */
- if(gjk.det( simplex.c[0]->w-simplex.c[3]->w,
- simplex.c[1]->w-simplex.c[3]->w,
- simplex.c[2]->w-simplex.c[3]->w)<0)
+ static inline void append(sList& list,sFace* face)
{
- btSwap(simplex.c[0],simplex.c[1]);
- btSwap(simplex.p[0],simplex.p[1]);
+ face->l[0] = 0;
+ face->l[1] = list.root;
+ if(list.root) list.root->l[0]=face;
+ list.root = face;
+ ++list.count;
}
- /* Build initial hull */
- sFace* tetra[]={newface(simplex.c[0],simplex.c[1],simplex.c[2],true),
+ static inline void remove(sList& list,sFace* face)
+ {
+ if(face->l[1]) face->l[1]->l[0]=face->l[0];
+ if(face->l[0]) face->l[0]->l[1]=face->l[1];
+ if(face==list.root) list.root=face->l[1];
+ --list.count;
+ }
+
+
+ void Initialize()
+ {
+ m_status = eStatus::Failed;
+ m_normal = btVector3(0,0,0);
+ m_depth = 0;
+ m_nextsv = 0;
+ for(U i=0;i<EPA_MAX_FACES;++i)
+ {
+ append(m_stock,&m_fc_store[EPA_MAX_FACES-i-1]);
+ }
+ }
+ eStatus::_ Evaluate(GJK& gjk,const btVector3& guess)
+ {
+ GJK::sSimplex& simplex=*gjk.m_simplex;
+ if((simplex.rank>1)&&gjk.EncloseOrigin())
+ {
+
+ /* Clean up */
+ while(m_hull.root)
+ {
+ sFace* f = m_hull.root;
+ remove(m_hull,f);
+ append(m_stock,f);
+ }
+ m_status = eStatus::Valid;
+ m_nextsv = 0;
+ /* Orient simplex */
+ if(gjk.det( simplex.c[0]->w-simplex.c[3]->w,
+ simplex.c[1]->w-simplex.c[3]->w,
+ simplex.c[2]->w-simplex.c[3]->w)<0)
+ {
+ btSwap(simplex.c[0],simplex.c[1]);
+ btSwap(simplex.p[0],simplex.p[1]);
+ }
+ /* Build initial hull */
+ sFace* tetra[]={newface(simplex.c[0],simplex.c[1],simplex.c[2],true),
newface(simplex.c[1],simplex.c[0],simplex.c[3],true),
newface(simplex.c[2],simplex.c[1],simplex.c[3],true),
newface(simplex.c[0],simplex.c[2],simplex.c[3],true)};
- if(m_hull.count==4)
- {
- sFace* best=findbest();
- sFace outer=*best;
- U pass=0;
- U iterations=0;
- bind(tetra[0],0,tetra[1],0);
- bind(tetra[0],1,tetra[2],0);
- bind(tetra[0],2,tetra[3],0);
- bind(tetra[1],1,tetra[3],2);
- bind(tetra[1],2,tetra[2],1);
- bind(tetra[2],2,tetra[3],1);
- m_status=eStatus::Valid;
- for(;iterations<EPA_MAX_ITERATIONS;++iterations)
- {
- if(m_nextsv<EPA_MAX_VERTICES)
- {
- sHorizon horizon;
- sSV* w=&m_sv_store[m_nextsv++];
- bool valid=true;
- best->pass = (U1)(++pass);
- gjk.getsupport(best->n,*w);
- const btScalar wdist=dot(best->n,w->w)-best->d;
- if(wdist>EPA_ACCURACY)
+ if(m_hull.count==4)
+ {
+ sFace* best=findbest();
+ sFace outer=*best;
+ U pass=0;
+ U iterations=0;
+ bind(tetra[0],0,tetra[1],0);
+ bind(tetra[0],1,tetra[2],0);
+ bind(tetra[0],2,tetra[3],0);
+ bind(tetra[1],1,tetra[3],2);
+ bind(tetra[1],2,tetra[2],1);
+ bind(tetra[2],2,tetra[3],1);
+ m_status=eStatus::Valid;
+ for(;iterations<EPA_MAX_ITERATIONS;++iterations)
{
- for(U j=0;(j<3)&&valid;++j)
- {
- valid&=expand( pass,w,
+ if(m_nextsv<EPA_MAX_VERTICES)
+ {
+ sHorizon horizon;
+ sSV* w=&m_sv_store[m_nextsv++];
+ bool valid=true;
+ best->pass = (U1)(++pass);
+ gjk.getsupport(best->n,*w);
+ const btScalar wdist=dot(best->n,w->w)-best->d;
+ if(wdist>EPA_ACCURACY)
+ {
+ for(U j=0;(j<3)&&valid;++j)
+ {
+ valid&=expand( pass,w,
best->f[j],best->e[j],
horizon);
- }
- if(valid&&(horizon.nf>=3))
- {
- bind(horizon.cf,1,horizon.ff,2);
- remove(m_hull,best);
- append(m_stock,best);
- best=findbest();
- if(best->p>=outer.p) outer=*best;
- } else { m_status=eStatus::InvalidHull;break; }
- } else { m_status=eStatus::AccuraryReached;break; }
- } else { m_status=eStatus::OutOfVertices;break; }
+ }
+ if(valid&&(horizon.nf>=3))
+ {
+ bind(horizon.cf,1,horizon.ff,2);
+ remove(m_hull,best);
+ append(m_stock,best);
+ best=findbest();
+ if(best->p>=outer.p) outer=*best;
+ } else { m_status=eStatus::InvalidHull;break; }
+ } else { m_status=eStatus::AccuraryReached;break; }
+ } else { m_status=eStatus::OutOfVertices;break; }
+ }
+ const btVector3 projection=outer.n*outer.d;
+ m_normal = outer.n;
+ m_depth = outer.d;
+ m_result.rank = 3;
+ m_result.c[0] = outer.c[0];
+ m_result.c[1] = outer.c[1];
+ m_result.c[2] = outer.c[2];
+ m_result.p[0] = cross( outer.c[1]->w-projection,
+ outer.c[2]->w-projection).length();
+ m_result.p[1] = cross( outer.c[2]->w-projection,
+ outer.c[0]->w-projection).length();
+ m_result.p[2] = cross( outer.c[0]->w-projection,
+ outer.c[1]->w-projection).length();
+ const btScalar sum=m_result.p[0]+m_result.p[1]+m_result.p[2];
+ m_result.p[0] /= sum;
+ m_result.p[1] /= sum;
+ m_result.p[2] /= sum;
+ return(m_status);
+ }
}
- const btVector3 projection=outer.n*outer.d;
- m_normal = outer.n;
- m_depth = outer.d;
- m_result.rank = 3;
- m_result.c[0] = outer.c[0];
- m_result.c[1] = outer.c[1];
- m_result.c[2] = outer.c[2];
- m_result.p[0] = cross( outer.c[1]->w-projection,
- outer.c[2]->w-projection).length();
- m_result.p[1] = cross( outer.c[2]->w-projection,
- outer.c[0]->w-projection).length();
- m_result.p[2] = cross( outer.c[0]->w-projection,
- outer.c[1]->w-projection).length();
- const btScalar sum=m_result.p[0]+m_result.p[1]+m_result.p[2];
- m_result.p[0] /= sum;
- m_result.p[1] /= sum;
- m_result.p[2] /= sum;
- return(m_status);
+ /* Fallback */
+ m_status = eStatus::FallBack;
+ m_normal = -guess;
+ const btScalar nl=m_normal.length();
+ if(nl>0)
+ m_normal = m_normal/nl;
+ else
+ m_normal = btVector3(1,0,0);
+ m_depth = 0;
+ m_result.rank=1;
+ m_result.c[0]=simplex.c[0];
+ m_result.p[0]=1;
+ return(m_status);
}
- }
- /* Fallback */
- m_status = eStatus::FallBack;
- m_normal = -guess;
- const btScalar nl=m_normal.length();
- if(nl>0)
- m_normal = m_normal/nl;
- else
- m_normal = btVector3(1,0,0);
- m_depth = 0;
- m_result.rank=1;
- m_result.c[0]=simplex.c[0];
- m_result.p[0]=1;
- return(m_status);
- }
-sFace* newface(sSV* a,sSV* b,sSV* c,bool forced)
- {
- if(m_stock.root)
- {
- sFace* face=m_stock.root;
- remove(m_stock,face);
- append(m_hull,face);
- face->pass = 0;
- face->c[0] = a;
- face->c[1] = b;
- face->c[2] = c;
- face->n = cross(b->w-a->w,c->w-a->w);
- const btScalar l=face->n.length();
- const bool v=l>EPA_ACCURACY;
- face->p = btMin(btMin(
- dot(a->w,cross(face->n,a->w-b->w)),
- dot(b->w,cross(face->n,b->w-c->w))),
- dot(c->w,cross(face->n,c->w-a->w))) /
- (v?l:1);
- face->p = face->p>=-EPA_INSIDE_EPS?0:face->p;
- if(v)
+ sFace* newface(sSV* a,sSV* b,sSV* c,bool forced)
{
- face->d = dot(a->w,face->n)/l;
- face->n /= l;
- if(forced||(face->d>=-EPA_PLANE_EPS))
+ if(m_stock.root)
{
- return(face);
- } else m_status=eStatus::NonConvex;
- } else m_status=eStatus::Degenerated;
- remove(m_hull,face);
- append(m_stock,face);
- return(0);
- }
- m_status=m_stock.root?eStatus::OutOfVertices:eStatus::OutOfFaces;
- return(0);
- }
-sFace* findbest()
- {
- sFace* minf=m_hull.root;
- btScalar mind=minf->d*minf->d;
- btScalar maxp=minf->p;
- for(sFace* f=minf->l[1];f;f=f->l[1])
- {
- const btScalar sqd=f->d*f->d;
- if((f->p>=maxp)&&(sqd<mind))
- {
- minf=f;
- mind=sqd;
- maxp=f->p;
+ sFace* face=m_stock.root;
+ remove(m_stock,face);
+ append(m_hull,face);
+ face->pass = 0;
+ face->c[0] = a;
+ face->c[1] = b;
+ face->c[2] = c;
+ face->n = cross(b->w-a->w,c->w-a->w);
+ const btScalar l=face->n.length();
+ const bool v=l>EPA_ACCURACY;
+ face->p = btMin(btMin(
+ dot(a->w,cross(face->n,a->w-b->w)),
+ dot(b->w,cross(face->n,b->w-c->w))),
+ dot(c->w,cross(face->n,c->w-a->w))) /
+ (v?l:1);
+ face->p = face->p>=-EPA_INSIDE_EPS?0:face->p;
+ if(v)
+ {
+ face->d = dot(a->w,face->n)/l;
+ face->n /= l;
+ if(forced||(face->d>=-EPA_PLANE_EPS))
+ {
+ return(face);
+ } else m_status=eStatus::NonConvex;
+ } else m_status=eStatus::Degenerated;
+ remove(m_hull,face);
+ append(m_stock,face);
+ return(0);
+ }
+ m_status=m_stock.root?eStatus::OutOfVertices:eStatus::OutOfFaces;
+ return(0);
}
- }
- return(minf);
- }
-bool expand(U pass,sSV* w,sFace* f,U e,sHorizon& horizon)
- {
- static const U i1m3[]={1,2,0};
- static const U i2m3[]={2,0,1};
- if(f->pass!=pass)
- {
- const U e1=i1m3[e];
- if((dot(f->n,w->w)-f->d)<-EPA_PLANE_EPS)
+ sFace* findbest()
{
- sFace* nf=newface(f->c[e1],f->c[e],w,false);
- if(nf)
+ sFace* minf=m_hull.root;
+ btScalar mind=minf->d*minf->d;
+ btScalar maxp=minf->p;
+ for(sFace* f=minf->l[1];f;f=f->l[1])
{
- bind(nf,0,f,e);
- if(horizon.cf) bind(horizon.cf,1,nf,2); else horizon.ff=nf;
- horizon.cf=nf;
- ++horizon.nf;
- return(true);
+ const btScalar sqd=f->d*f->d;
+ if((f->p>=maxp)&&(sqd<mind))
+ {
+ minf=f;
+ mind=sqd;
+ maxp=f->p;
+ }
}
+ return(minf);
}
- else
+ bool expand(U pass,sSV* w,sFace* f,U e,sHorizon& horizon)
{
- const U e2=i2m3[e];
- f->pass = (U1)pass;
- if( expand(pass,w,f->f[e1],f->e[e1],horizon)&&
- expand(pass,w,f->f[e2],f->e[e2],horizon))
+ static const U i1m3[]={1,2,0};
+ static const U i2m3[]={2,0,1};
+ if(f->pass!=pass)
{
- remove(m_hull,f);
- append(m_stock,f);
- return(true);
+ const U e1=i1m3[e];
+ if((dot(f->n,w->w)-f->d)<-EPA_PLANE_EPS)
+ {
+ sFace* nf=newface(f->c[e1],f->c[e],w,false);
+ if(nf)
+ {
+ bind(nf,0,f,e);
+ if(horizon.cf) bind(horizon.cf,1,nf,2); else horizon.ff=nf;
+ horizon.cf=nf;
+ ++horizon.nf;
+ return(true);
+ }
+ }
+ else
+ {
+ const U e2=i2m3[e];
+ f->pass = (U1)pass;
+ if( expand(pass,w,f->f[e1],f->e[e1],horizon)&&
+ expand(pass,w,f->f[e2],f->e[e2],horizon))
+ {
+ remove(m_hull,f);
+ append(m_stock,f);
+ return(true);
+ }
+ }
}
+ return(false);
}
- }
- return(false);
- }
-};
+ };
-//
-static void Initialize( const btConvexShape* shape0,const btTransform& wtrs0,
- const btConvexShape* shape1,const btTransform& wtrs1,
- btGjkEpaSolver2::sResults& results,
- tShape& shape,
- bool withmargins)
-{
-/* Results */
-results.witnesses[0] =
-results.witnesses[1] = btVector3(0,0,0);
-results.status = btGjkEpaSolver2::sResults::Separated;
-/* Shape */
-shape.m_shapes[0] = shape0;
-shape.m_shapes[1] = shape1;
-shape.m_toshape1 = wtrs1.getBasis().transposeTimes(wtrs0.getBasis());
-shape.m_toshape0 = wtrs0.inverseTimes(wtrs1);
-shape.EnableMargin(withmargins);
-}
+ //
+ static void Initialize( const btConvexShape* shape0,const btTransform& wtrs0,
+ const btConvexShape* shape1,const btTransform& wtrs1,
+ btGjkEpaSolver2::sResults& results,
+ tShape& shape,
+ bool withmargins)
+ {
+ /* Results */
+ results.witnesses[0] =
+ results.witnesses[1] = btVector3(0,0,0);
+ results.status = btGjkEpaSolver2::sResults::Separated;
+ /* Shape */
+ shape.m_shapes[0] = shape0;
+ shape.m_shapes[1] = shape1;
+ shape.m_toshape1 = wtrs1.getBasis().transposeTimes(wtrs0.getBasis());
+ shape.m_toshape0 = wtrs0.inverseTimes(wtrs1);
+ shape.EnableMargin(withmargins);
+ }
}
@@ -775,87 +775,87 @@ using namespace gjkepa2_impl;
//
int btGjkEpaSolver2::StackSizeRequirement()
{
-return(sizeof(GJK)+sizeof(EPA));
+ return(sizeof(GJK)+sizeof(EPA));
}
//
bool btGjkEpaSolver2::Distance( const btConvexShape* shape0,
- const btTransform& wtrs0,
- const btConvexShape* shape1,
- const btTransform& wtrs1,
- const btVector3& guess,
- sResults& results)
+ const btTransform& wtrs0,
+ const btConvexShape* shape1,
+ const btTransform& wtrs1,
+ const btVector3& guess,
+ sResults& results)
{
-tShape shape;
-Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,false);
-GJK gjk;
-GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,guess);
-if(gjk_status==GJK::eStatus::Valid)
+ tShape shape;
+ Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,false);
+ GJK gjk;
+ GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,guess);
+ if(gjk_status==GJK::eStatus::Valid)
{
- btVector3 w0=btVector3(0,0,0);
- btVector3 w1=btVector3(0,0,0);
- for(U i=0;i<gjk.m_simplex->rank;++i)
+ btVector3 w0=btVector3(0,0,0);
+ btVector3 w1=btVector3(0,0,0);
+ for(U i=0;i<gjk.m_simplex->rank;++i)
{
- const btScalar p=gjk.m_simplex->p[i];
- w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p;
- w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p;
+ const btScalar p=gjk.m_simplex->p[i];
+ w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p;
+ w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p;
}
- results.witnesses[0] = wtrs0*w0;
- results.witnesses[1] = wtrs0*w1;
- results.normal = w0-w1;
- results.distance = results.normal.length();
- results.normal /= results.distance>GJK_MIN_DISTANCE?results.distance:1;
- return(true);
+ results.witnesses[0] = wtrs0*w0;
+ results.witnesses[1] = wtrs0*w1;
+ results.normal = w0-w1;
+ results.distance = results.normal.length();
+ results.normal /= results.distance>GJK_MIN_DISTANCE?results.distance:1;
+ return(true);
}
else
{
- results.status = gjk_status==GJK::eStatus::Inside?
- sResults::Penetrating :
- sResults::GJK_Failed ;
- return(false);
+ results.status = gjk_status==GJK::eStatus::Inside?
+ sResults::Penetrating :
+ sResults::GJK_Failed ;
+ return(false);
}
}
//
bool btGjkEpaSolver2::Penetration( const btConvexShape* shape0,
- const btTransform& wtrs0,
- const btConvexShape* shape1,
- const btTransform& wtrs1,
- const btVector3& guess,
- sResults& results,
- bool usemargins)
+ const btTransform& wtrs0,
+ const btConvexShape* shape1,
+ const btTransform& wtrs1,
+ const btVector3& guess,
+ sResults& results,
+ bool usemargins)
{
-tShape shape;
-Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,usemargins);
-GJK gjk;
-GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,-guess);
-switch(gjk_status)
+ tShape shape;
+ Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,usemargins);
+ GJK gjk;
+ GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,-guess);
+ switch(gjk_status)
{
case GJK::eStatus::Inside:
{
- EPA epa;
- EPA::eStatus::_ epa_status=epa.Evaluate(gjk,-guess);
- if(epa_status!=EPA::eStatus::Failed)
+ EPA epa;
+ EPA::eStatus::_ epa_status=epa.Evaluate(gjk,-guess);
+ if(epa_status!=EPA::eStatus::Failed)
{
- btVector3 w0=btVector3(0,0,0);
- for(U i=0;i<epa.m_result.rank;++i)
+ btVector3 w0=btVector3(0,0,0);
+ for(U i=0;i<epa.m_result.rank;++i)
{
- w0+=shape.Support(epa.m_result.c[i]->d,0)*epa.m_result.p[i];
+ w0+=shape.Support(epa.m_result.c[i]->d,0)*epa.m_result.p[i];
}
- results.status = sResults::Penetrating;
- results.witnesses[0] = wtrs0*w0;
- results.witnesses[1] = wtrs0*(w0-epa.m_normal*epa.m_depth);
- results.normal = -epa.m_normal;
- results.distance = -epa.m_depth;
- return(true);
+ results.status = sResults::Penetrating;
+ results.witnesses[0] = wtrs0*w0;
+ results.witnesses[1] = wtrs0*(w0-epa.m_normal*epa.m_depth);
+ results.normal = -epa.m_normal;
+ results.distance = -epa.m_depth;
+ return(true);
} else results.status=sResults::EPA_Failed;
}
- break;
+ break;
case GJK::eStatus::Failed:
- results.status=sResults::GJK_Failed;
- break;
+ results.status=sResults::GJK_Failed;
+ break;
}
-return(false);
+ return(false);
}
//
@@ -865,49 +865,49 @@ btScalar btGjkEpaSolver2::SignedDistance(const btVector3& position,
const btTransform& wtrs0,
sResults& results)
{
-tShape shape;
-btSphereShape shape1(margin);
-btTransform wtrs1(btQuaternion(0,0,0,1),position);
-Initialize(shape0,wtrs0,&shape1,wtrs1,results,shape,false);
-GJK gjk;
-GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,btVector3(1,1,1));
-if(gjk_status==GJK::eStatus::Valid)
+ tShape shape;
+ btSphereShape shape1(margin);
+ btTransform wtrs1(btQuaternion(0,0,0,1),position);
+ Initialize(shape0,wtrs0,&shape1,wtrs1,results,shape,false);
+ GJK gjk;
+ GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,btVector3(1,1,1));
+ if(gjk_status==GJK::eStatus::Valid)
{
- btVector3 w0=btVector3(0,0,0);
- btVector3 w1=btVector3(0,0,0);
- for(U i=0;i<gjk.m_simplex->rank;++i)
+ btVector3 w0=btVector3(0,0,0);
+ btVector3 w1=btVector3(0,0,0);
+ for(U i=0;i<gjk.m_simplex->rank;++i)
{
- const btScalar p=gjk.m_simplex->p[i];
- w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p;
- w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p;
+ const btScalar p=gjk.m_simplex->p[i];
+ w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p;
+ w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p;
}
- results.witnesses[0] = wtrs0*w0;
- results.witnesses[1] = wtrs0*w1;
- const btVector3 delta= results.witnesses[1]-
- results.witnesses[0];
- const btScalar margin= shape0->getMargin()+
- shape1.getMargin();
- const btScalar length= delta.length();
- results.normal = delta/length;
- results.witnesses[0] += results.normal*margin;
- return(length-margin);
+ results.witnesses[0] = wtrs0*w0;
+ results.witnesses[1] = wtrs0*w1;
+ const btVector3 delta= results.witnesses[1]-
+ results.witnesses[0];
+ const btScalar margin= shape0->getMarginNonVirtual()+
+ shape1.getMarginNonVirtual();
+ const btScalar length= delta.length();
+ results.normal = delta/length;
+ results.witnesses[0] += results.normal*margin;
+ return(length-margin);
}
else
{
- if(gjk_status==GJK::eStatus::Inside)
+ if(gjk_status==GJK::eStatus::Inside)
{
- if(Penetration(shape0,wtrs0,&shape1,wtrs1,gjk.m_ray,results))
+ if(Penetration(shape0,wtrs0,&shape1,wtrs1,gjk.m_ray,results))
{
- const btVector3 delta= results.witnesses[0]-
- results.witnesses[1];
- const btScalar length= delta.length();
- if (length >= SIMD_EPSILON)
- results.normal = delta/length;
- return(-length);
+ const btVector3 delta= results.witnesses[0]-
+ results.witnesses[1];
+ const btScalar length= delta.length();
+ if (length >= SIMD_EPSILON)
+ results.normal = delta/length;
+ return(-length);
}
}
}
-return(SIMD_INFINITY);
+ return(SIMD_INFINITY);
}
//
@@ -918,10 +918,10 @@ bool btGjkEpaSolver2::SignedDistance(const btConvexShape* shape0,
const btVector3& guess,
sResults& results)
{
-if(!Distance(shape0,wtrs0,shape1,wtrs1,guess,results))
- return(Penetration(shape0,wtrs0,shape1,wtrs1,guess,results,false));
+ if(!Distance(shape0,wtrs0,shape1,wtrs1,guess,results))
+ return(Penetration(shape0,wtrs0,shape1,wtrs1,guess,results,false));
else
- return(true);
+ return(true);
}
/* Symbols cleanup */
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
index c4f84ed4d75..05573c7cfce 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
@@ -17,13 +17,14 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "btGjkEpaPenetrationDepthSolver.h"
-#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h"
+
+
#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
bool btGjkEpaPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& simplexSolver,
const btConvexShape* pConvexA, const btConvexShape* pConvexB,
const btTransform& transformA, const btTransform& transformB,
- btVector3& v, btPoint3& wWitnessOnA, btPoint3& wWitnessOnB,
+ btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB,
class btIDebugDraw* debugDraw, btStackAlloc* stackAlloc )
{
@@ -33,20 +34,12 @@ bool btGjkEpaPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& sim
const btScalar radialmargin(btScalar(0.));
-//#define USE_ORIGINAL_GJK 1
-#ifdef USE_ORIGINAL_GJK
- btGjkEpaSolver::sResults results;
- if(btGjkEpaSolver::Collide( pConvexA,transformA,
- pConvexB,transformB,
- radialmargin,stackAlloc,results))
-#else
btVector3 guessVector(transformA.getOrigin()-transformB.getOrigin());
btGjkEpaSolver2::sResults results;
if(btGjkEpaSolver2::Penetration(pConvexA,transformA,
pConvexB,transformB,
guessVector,results))
-#endif
{
// debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0));
//resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth);
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
index 2dc069ce5cf..68dbc566518 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
@@ -28,7 +28,7 @@ class btGjkEpaPenetrationDepthSolver : public btConvexPenetrationDepthSolver
bool calcPenDepth( btSimplexSolverInterface& simplexSolver,
const btConvexShape* pConvexA, const btConvexShape* pConvexB,
const btTransform& transformA, const btTransform& transformB,
- btVector3& v, btPoint3& wWitnessOnA, btPoint3& wWitnessOnB,
+ btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB,
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc );
private :
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
index 01fb1a4b068..0856332d1ca 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
@@ -18,11 +18,15 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h"
+
+
#if defined(DEBUG) || defined (_DEBUG)
+//#define TEST_NON_VIRTUAL 1
#include <stdio.h> //for debug printf
#ifdef __SPU__
#include <spu_printf.h>
#define printf spu_printf
+//#define DEBUG_SPU_COLLISION_DETECTION 1
#endif //__SPU__
#endif
@@ -49,6 +53,8 @@ m_catchDegeneracies(1)
void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults)
{
+ m_cachedSeparatingDistance = 0.f;
+
btScalar distance=btScalar(0.);
btVector3 normalInB(btScalar(0.),btScalar(0.),btScalar(0.));
btVector3 pointOnA,pointOnB;
@@ -58,16 +64,35 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
localTransA.getOrigin() -= positionOffset;
localTransB.getOrigin() -= positionOffset;
+#ifdef __SPU__
+ btScalar marginA = m_minkowskiA->getMarginNonVirtual();
+ btScalar marginB = m_minkowskiB->getMarginNonVirtual();
+#else
btScalar marginA = m_minkowskiA->getMargin();
btScalar marginB = m_minkowskiB->getMargin();
+#ifdef TEST_NON_VIRTUAL
+ btScalar marginAv = m_minkowskiA->getMarginNonVirtual();
+ btScalar marginBv = m_minkowskiB->getMarginNonVirtual();
+ btAssert(marginA == marginAv);
+ btAssert(marginB == marginBv);
+#endif //TEST_NON_VIRTUAL
+#endif
+
+
gNumGjkChecks++;
+#ifdef DEBUG_SPU_COLLISION_DETECTION
+ spu_printf("inside gjk\n");
+#endif
//for CCD we don't use margins
if (m_ignoreMargin)
{
marginA = btScalar(0.);
marginB = btScalar(0.);
+#ifdef DEBUG_SPU_COLLISION_DETECTION
+ spu_printf("ignoring margin\n");
+#endif
}
m_curIter = 0;
@@ -98,18 +123,35 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
btVector3 seperatingAxisInA = (-m_cachedSeparatingAxis)* input.m_transformA.getBasis();
btVector3 seperatingAxisInB = m_cachedSeparatingAxis* input.m_transformB.getBasis();
+#ifdef __SPU__
+ btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
+ btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
+#else
btVector3 pInA = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA);
btVector3 qInB = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB);
- btPoint3 pWorld = localTransA(pInA);
- btPoint3 qWorld = localTransB(qInB);
-
+#ifdef TEST_NON_VIRTUAL
+ btVector3 pInAv = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA);
+ btVector3 qInBv = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB);
+ btAssert((pInAv-pInA).length() < 0.0001);
+ btAssert((qInBv-qInB).length() < 0.0001);
+#endif //
+#endif //__SPU__
+
+ btVector3 pWorld = localTransA(pInA);
+ btVector3 qWorld = localTransB(qInB);
+
+#ifdef DEBUG_SPU_COLLISION_DETECTION
+ spu_printf("got local supporting vertices\n");
+#endif
+
btVector3 w = pWorld - qWorld;
delta = m_cachedSeparatingAxis.dot(w);
// potential exit, they don't overlap
if ((delta > btScalar(0.0)) && (delta * delta > squaredDistance * input.m_maximumDistanceSquared))
{
- checkPenetration = false;
+ checkSimplex=true;
+ //checkPenetration = false;
break;
}
@@ -133,9 +175,15 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
checkSimplex = true;
break;
}
+
+#ifdef DEBUG_SPU_COLLISION_DETECTION
+ spu_printf("addVertex 1\n");
+#endif
//add current vertex to simplex
m_simplexSolver->addVertex(w, pWorld, qWorld);
-
+#ifdef DEBUG_SPU_COLLISION_DETECTION
+ spu_printf("addVertex 2\n");
+#endif
//calculate the closest point to the origin (update vector v)
if (!m_simplexSolver->closest(m_cachedSeparatingAxis))
{
@@ -167,7 +215,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
//degeneracy, this is typically due to invalid/uninitialized worldtransforms for a btCollisionObject
if (m_curIter++ > gGjkMaxIter)
{
- #if defined(DEBUG) || defined (_DEBUG)
+ #if defined(DEBUG) || defined (_DEBUG) || defined (DEBUG_SPU_COLLISION_DETECTION)
printf("btGjkPairDetector maxIter exceeded:%i\n",m_curIter);
printf("sepAxis=(%f,%f,%f), squaredDistance = %f, shapeTypeA=%i,shapeTypeB=%i\n",
@@ -290,10 +338,20 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
#endif //__CELLOS_LV2__
+#ifdef DEBUG_SPU_COLLISION_DETECTION
+ spu_printf("output 1\n");
+#endif
+ m_cachedSeparatingAxis = normalInB;
+ m_cachedSeparatingDistance = distance;
+
output.addContactPoint(
normalInB,
pointOnB+positionOffset,
distance);
+
+#ifdef DEBUG_SPU_COLLISION_DETECTION
+ spu_printf("output 2\n");
+#endif
//printf("gjk add:%f",distance);
}
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
index 550fc4677e0..0ad4aab8a59 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
@@ -20,7 +20,6 @@ subject to the following restrictions:
#define GJK_PAIR_DETECTOR_H
#include "btDiscreteCollisionDetectorInterface.h"
-#include "LinearMath/btPoint3.h"
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
class btConvexShape;
@@ -38,6 +37,7 @@ class btGjkPairDetector : public btDiscreteCollisionDetectorInterface
const btConvexShape* m_minkowskiA;
const btConvexShape* m_minkowskiB;
bool m_ignoreMargin;
+ btScalar m_cachedSeparatingDistance;
public:
@@ -68,6 +68,15 @@ public:
m_cachedSeparatingAxis = seperatingAxis;
}
+ const btVector3& getCachedSeparatingAxis() const
+ {
+ return m_cachedSeparatingAxis;
+ }
+ btScalar getCachedSeparatingDistance() const
+ {
+ return m_cachedSeparatingDistance;
+ }
+
void setPenetrationDepthSolver(btConvexPenetrationDepthSolver* penetrationDepthSolver)
{
m_penetrationDepthSolver = penetrationDepthSolver;
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
index e75fc1bee96..c7c9812985d 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
@@ -32,6 +32,8 @@ class btManifoldPoint
:m_userPersistentData(0),
m_appliedImpulse(0.f),
m_lateralFrictionInitialized(false),
+ m_appliedImpulseLateral1(0.f),
+ m_appliedImpulseLateral2(0.f),
m_lifeTime(0)
{
}
@@ -110,6 +112,12 @@ class btManifoldPoint
m_distance1 = dist;
}
+ ///this returns the most recent applied impulse, to satisfy contact constraints by the constraint solver
+ btScalar getAppliedImpulse() const
+ {
+ return m_appliedImpulse;
+ }
+
};
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
index 0e6fa2e6dfe..581b4258f03 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
@@ -19,9 +19,6 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
-
-
-
#define NUM_UNITSPHERE_POINTS 42
static btVector3 sPenetrationDirections[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2] =
{
@@ -73,7 +70,7 @@ btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654))
bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& simplexSolver,
const btConvexShape* convexA,const btConvexShape* convexB,
const btTransform& transA,const btTransform& transB,
- btVector3& v, btPoint3& pa, btPoint3& pb,
+ btVector3& v, btVector3& pa, btVector3& pb,
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
)
{
@@ -117,7 +114,9 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s
btVector3 seperatingAxisInA,seperatingAxisInB;
btVector3 pInA,qInB,pWorld,qWorld,w;
+#ifndef __SPU__
#define USE_BATCHED_SUPPORT 1
+#endif
#ifdef USE_BATCHED_SUPPORT
btVector3 supportVerticesABatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2];
@@ -200,6 +199,7 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s
int numSampleDirections = NUM_UNITSPHERE_POINTS;
+#ifndef __SPU__
{
int numPDA = convexA->getNumPreferredPenetrationDirections();
if (numPDA)
@@ -229,14 +229,15 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s
}
}
}
+#endif // __SPU__
for (int i=0;i<numSampleDirections;i++)
{
const btVector3& norm = sPenetrationDirections[i];
seperatingAxisInA = (-norm)* transA.getBasis();
seperatingAxisInB = norm* transB.getBasis();
- pInA = convexA->localGetSupportingVertexWithoutMargin(seperatingAxisInA);
- qInB = convexB->localGetSupportingVertexWithoutMargin(seperatingAxisInB);
+ pInA = convexA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
+ qInB = convexB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
pWorld = transA(pInA);
qWorld = transB(qInB);
w = qWorld - pWorld;
@@ -254,13 +255,13 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s
//add the margins
- minA += minNorm*convexA->getMargin();
- minB -= minNorm*convexB->getMargin();
+ minA += minNorm*convexA->getMarginNonVirtual();
+ minB -= minNorm*convexB->getMarginNonVirtual();
//no penetration
if (minProj < btScalar(0.))
return false;
- minProj += (convexA->getMargin() + convexB->getMargin());
+ minProj += (convexA->getMarginNonVirtual() + convexB->getMarginNonVirtual());
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
index 27b42c2b47e..23cbd57ac7e 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
@@ -27,10 +27,9 @@ public:
virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver,
const btConvexShape* convexA,const btConvexShape* convexB,
const btTransform& transA,const btTransform& transB,
- btVector3& v, btPoint3& pa, btPoint3& pb,
+ btVector3& v, btVector3& pa, btVector3& pb,
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
);
-
};
#endif //MINKOWSKI_PENETRATION_DEPTH_SOLVER_H
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
index 386885d2ac8..d4e29882d37 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
@@ -16,7 +16,7 @@ subject to the following restrictions:
#include "btPersistentManifold.h"
#include "LinearMath/btTransform.h"
-#include <assert.h>
+
btScalar gContactBreakingThreshold = btScalar(0.02);
ContactDestroyedCallback gContactDestroyedCallback = 0;
@@ -66,7 +66,7 @@ void btPersistentManifold::clearUserCache(btManifoldPoint& pt)
printf("error in clearUserCache\n");
}
}
- assert(occurance<=0);
+ btAssert(occurance<=0);
#endif //DEBUG_PERSISTENCY
if (pt.m_userPersistentData && gContactDestroyedCallback)
@@ -164,7 +164,7 @@ int btPersistentManifold::getCacheEntry(const btManifoldPoint& newPoint) const
int btPersistentManifold::addManifoldPoint(const btManifoldPoint& newPoint)
{
- assert(validContactDistance(newPoint));
+ btAssert(validContactDistance(newPoint));
int insertIndex = getNumContacts();
if (insertIndex == MANIFOLD_CACHE_SIZE)
@@ -183,6 +183,9 @@ int btPersistentManifold::addManifoldPoint(const btManifoldPoint& newPoint)
}
+ if (insertIndex<0)
+ insertIndex=0;
+
btAssert(m_pointCache[insertIndex].m_userPersistentData==0);
m_pointCache[insertIndex] = newPoint;
return insertIndex;
@@ -190,7 +193,7 @@ int btPersistentManifold::addManifoldPoint(const btManifoldPoint& newPoint)
btScalar btPersistentManifold::getContactBreakingThreshold() const
{
- return gContactBreakingThreshold;
+ return m_contactBreakingThreshold;
}
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
index c122eb865e8..0b3c734d1d7 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
@@ -24,7 +24,7 @@ subject to the following restrictions:
struct btCollisionResult;
-///contact breaking and merging threshold
+///maximum contact breaking and merging threshold
extern btScalar gContactBreakingThreshold;
typedef bool (*ContactDestroyedCallback)(void* userPersistentData);
@@ -54,6 +54,9 @@ ATTRIBUTE_ALIGNED16( class) btPersistentManifold
void* m_body1;
int m_cachedPoints;
+ btScalar m_contactBreakingThreshold;
+ btScalar m_contactProcessingThreshold;
+
/// sort cached points so most isolated points come first
int sortCachedPoints(const btManifoldPoint& pt);
@@ -68,10 +71,12 @@ public:
btPersistentManifold();
- btPersistentManifold(void* body0,void* body1,int bla)
- : m_body0(body0),m_body1(body1),m_cachedPoints(0)
+ btPersistentManifold(void* body0,void* body1,int , btScalar contactBreakingThreshold,btScalar contactProcessingThreshold)
+ : m_body0(body0),m_body1(body1),m_cachedPoints(0),
+ m_contactBreakingThreshold(contactBreakingThreshold),
+ m_contactProcessingThreshold(contactProcessingThreshold)
{
- (void)bla;
+
}
SIMD_FORCE_INLINE void* getBody0() { return m_body0;}
@@ -106,8 +111,13 @@ public:
return m_pointCache[index];
}
- /// todo: get this margin from the current physics / collision environment
+ ///@todo: get this margin from the current physics / collision environment
btScalar getContactBreakingThreshold() const;
+
+ btScalar getContactProcessingThreshold() const
+ {
+ return m_contactProcessingThreshold;
+ }
int getCacheEntry(const btManifoldPoint& newPoint) const;
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
index a70a3ae56c4..cdb1d22444d 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
@@ -23,10 +23,12 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
#include "btRaycastCallback.h"
-btTriangleRaycastCallback::btTriangleRaycastCallback(const btVector3& from,const btVector3& to)
+btTriangleRaycastCallback::btTriangleRaycastCallback(const btVector3& from,const btVector3& to, unsigned int flags)
:
m_from(from),
m_to(to),
+ //@BP Mod
+ m_flags(flags),
m_hitFraction(btScalar(1.))
{
@@ -55,6 +57,12 @@ void btTriangleRaycastCallback::processTriangle(btVector3* triangle,int partId,
{
return ; // same sign
}
+ //@BP Mod - Backface filtering
+ if (((m_flags & kF_FilterBackfaces) != 0) && (dist_a > btScalar(0.0)))
+ {
+ // Backface, skip check
+ return;
+ }
const btScalar proj_length=dist_a-dist_b;
const btScalar distance = (dist_a)/(proj_length);
@@ -89,14 +97,18 @@ void btTriangleRaycastCallback::processTriangle(btVector3* triangle,int partId,
if ( (btScalar)(cp2.dot(triangleNormal)) >=edge_tolerance)
{
+ //@BP Mod
+ // Triangle normal isn't normalized
+ triangleNormal.normalize();
- if ( dist_a > 0 )
+ //@BP Mod - Allow for unflipped normal when raycasting against backfaces
+ if (((m_flags & kF_KeepUnflippedNormal) != 0) || (dist_a <= btScalar(0.0)))
{
- m_hitFraction = reportHit(triangleNormal,distance,partId,triangleIndex);
+ m_hitFraction = reportHit(-triangleNormal,distance,partId,triangleIndex);
}
else
{
- m_hitFraction = reportHit(-triangleNormal,distance,partId,triangleIndex);
+ m_hitFraction = reportHit(triangleNormal,distance,partId,triangleIndex);
}
}
}
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
index d2b4b80f8ba..3a1ab388c13 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
@@ -29,9 +29,20 @@ public:
btVector3 m_from;
btVector3 m_to;
+ //@BP Mod - allow backface filtering and unflipped normals
+ enum EFlags
+ {
+ kF_None = 0,
+ kF_FilterBackfaces = 1 << 0,
+ kF_KeepUnflippedNormal = 1 << 1, // Prevents returned face normal getting flipped when a ray hits a back-facing triangle
+
+ kF_Terminator = 0xFFFFFFFF
+ };
+ unsigned int m_flags;
+
btScalar m_hitFraction;
- btTriangleRaycastCallback(const btVector3& from,const btVector3& to);
+ btTriangleRaycastCallback(const btVector3& from,const btVector3& to, unsigned int flags=0);
virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex);
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h
index cf65f46505b..823b4e7158b 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h
@@ -19,7 +19,6 @@ subject to the following restrictions:
#define SIMPLEX_SOLVER_INTERFACE_H
#include "LinearMath/btVector3.h"
-#include "LinearMath/btPoint3.h"
#define NO_VIRTUAL_INTERFACE 1
#ifdef NO_VIRTUAL_INTERFACE
@@ -37,7 +36,7 @@ class btSimplexSolverInterface
virtual void reset() = 0;
- virtual void addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q) = 0;
+ virtual void addVertex(const btVector3& w, const btVector3& p, const btVector3& q) = 0;
virtual bool closest(btVector3& v) = 0;
@@ -45,7 +44,7 @@ class btSimplexSolverInterface
virtual bool fullSimplex() const = 0;
- virtual int getSimplex(btPoint3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const = 0;
+ virtual int getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const = 0;
virtual bool inSimplex(const btVector3& w) = 0;
@@ -53,7 +52,7 @@ class btSimplexSolverInterface
virtual bool emptySimplex() const = 0;
- virtual void compute_points(btPoint3& p1, btPoint3& p2) = 0;
+ virtual void compute_points(btVector3& p1, btVector3& p2) = 0;
virtual int numVertices() const =0;
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
index cf8a3ab5eb1..a7ffeda8c62 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
@@ -25,8 +25,6 @@ subject to the following restrictions:
#include "btVoronoiSimplexSolver.h"
-#include <assert.h>
-//#include <stdio.h>
#define VERTA 0
#define VERTB 1
@@ -37,7 +35,7 @@ subject to the following restrictions:
void btVoronoiSimplexSolver::removeVertex(int index)
{
- assert(m_numVertices>0);
+ btAssert(m_numVertices>0);
m_numVertices--;
m_simplexVectorW[index] = m_simplexVectorW[m_numVertices];
m_simplexPointsP[index] = m_simplexPointsP[m_numVertices];
@@ -77,7 +75,7 @@ void btVoronoiSimplexSolver::reset()
//add a vertex
-void btVoronoiSimplexSolver::addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q)
+void btVoronoiSimplexSolver::addVertex(const btVector3& w, const btVector3& p, const btVector3& q)
{
m_lastW = w;
m_needsUpdate = true;
@@ -267,7 +265,7 @@ btScalar btVoronoiSimplexSolver::maxVertex()
//return the current simplex
-int btVoronoiSimplexSolver::getSimplex(btPoint3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const
+int btVoronoiSimplexSolver::getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const
{
int i;
for (i=0;i<numVertices();i++)
@@ -314,7 +312,7 @@ bool btVoronoiSimplexSolver::emptySimplex() const
}
-void btVoronoiSimplexSolver::compute_points(btPoint3& p1, btPoint3& p2)
+void btVoronoiSimplexSolver::compute_points(btVector3& p1, btVector3& p2)
{
updateClosestVectorAndPoints();
p1 = m_cachedP1;
@@ -325,7 +323,7 @@ void btVoronoiSimplexSolver::compute_points(btPoint3& p1, btPoint3& p2)
-bool btVoronoiSimplexSolver::closestPtPointTriangle(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c,btSubSimplexClosestResult& result)
+bool btVoronoiSimplexSolver::closestPtPointTriangle(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c,btSubSimplexClosestResult& result)
{
result.m_usedVertices.reset();
@@ -425,7 +423,7 @@ bool btVoronoiSimplexSolver::closestPtPointTriangle(const btPoint3& p, const btP
/// Test if point p and d lie on opposite sides of plane through abc
-int btVoronoiSimplexSolver::pointOutsideOfPlane(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d)
+int btVoronoiSimplexSolver::pointOutsideOfPlane(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d)
{
btVector3 normal = (b-a).cross(c-a);
@@ -452,7 +450,7 @@ if (signd * signd < (btScalar(1e-8) * btScalar(1e-8)))
}
-bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d, btSubSimplexClosestResult& finalResult)
+bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, btSubSimplexClosestResult& finalResult)
{
btSubSimplexClosestResult tempResult;
@@ -486,7 +484,7 @@ bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btPoint3& p, const
if (pointOutsideABC)
{
closestPtPointTriangle(p, a, b, c,tempResult);
- btPoint3 q = tempResult.m_closestPointOnSimplex;
+ btVector3 q = tempResult.m_closestPointOnSimplex;
btScalar sqDist = (q - p).dot( q - p);
// Update best closest point if (squared) distance is less than current best
@@ -513,7 +511,7 @@ bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btPoint3& p, const
if (pointOutsideACD)
{
closestPtPointTriangle(p, a, c, d,tempResult);
- btPoint3 q = tempResult.m_closestPointOnSimplex;
+ btVector3 q = tempResult.m_closestPointOnSimplex;
//convert result bitmask!
btScalar sqDist = (q - p).dot( q - p);
@@ -541,7 +539,7 @@ bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btPoint3& p, const
if (pointOutsideADB)
{
closestPtPointTriangle(p, a, d, b,tempResult);
- btPoint3 q = tempResult.m_closestPointOnSimplex;
+ btVector3 q = tempResult.m_closestPointOnSimplex;
//convert result bitmask!
btScalar sqDist = (q - p).dot( q - p);
@@ -569,7 +567,7 @@ bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btPoint3& p, const
if (pointOutsideBDC)
{
closestPtPointTriangle(p, b, d, c,tempResult);
- btPoint3 q = tempResult.m_closestPointOnSimplex;
+ btVector3 q = tempResult.m_closestPointOnSimplex;
//convert result bitmask!
btScalar sqDist = (q - p).dot( q - p);
if (sqDist < bestSqDist)
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
index 356d335bc93..d3162d9fbeb 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
@@ -50,7 +50,7 @@ struct btUsageBitfield{
struct btSubSimplexClosestResult
{
- btPoint3 m_closestPointOnSimplex;
+ btVector3 m_closestPointOnSimplex;
//MASK for m_usedVertices
//stores the simplex vertex-usage, using the MASK,
// if m_usedVertices & MASK then the related vertex is used
@@ -97,13 +97,13 @@ public:
int m_numVertices;
btVector3 m_simplexVectorW[VORONOI_SIMPLEX_MAX_VERTS];
- btPoint3 m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS];
- btPoint3 m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS];
+ btVector3 m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS];
+ btVector3 m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS];
- btPoint3 m_cachedP1;
- btPoint3 m_cachedP2;
+ btVector3 m_cachedP1;
+ btVector3 m_cachedP2;
btVector3 m_cachedV;
btVector3 m_lastW;
bool m_cachedValidClosest;
@@ -116,15 +116,15 @@ public:
void reduceVertices (const btUsageBitfield& usedVerts);
bool updateClosestVectorAndPoints();
- bool closestPtPointTetrahedron(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d, btSubSimplexClosestResult& finalResult);
- int pointOutsideOfPlane(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d);
- bool closestPtPointTriangle(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c,btSubSimplexClosestResult& result);
+ bool closestPtPointTetrahedron(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, btSubSimplexClosestResult& finalResult);
+ int pointOutsideOfPlane(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d);
+ bool closestPtPointTriangle(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c,btSubSimplexClosestResult& result);
public:
void reset();
- void addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q);
+ void addVertex(const btVector3& w, const btVector3& p, const btVector3& q);
bool closest(btVector3& v);
@@ -136,7 +136,7 @@ public:
return (m_numVertices == 4);
}
- int getSimplex(btPoint3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const;
+ int getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const;
bool inSimplex(const btVector3& w);
@@ -144,7 +144,7 @@ public:
bool emptySimplex() const ;
- void compute_points(btPoint3& p1, btPoint3& p2) ;
+ void compute_points(btVector3& p1, btVector3& p2) ;
int numVertices() const
{
diff --git a/extern/bullet2/src/BulletDynamics/CMakeLists.txt b/extern/bullet2/src/BulletDynamics/CMakeLists.txt
index 58b023e9775..ecfcbfef929 100644
--- a/extern/bullet2/src/BulletDynamics/CMakeLists.txt
+++ b/extern/bullet2/src/BulletDynamics/CMakeLists.txt
@@ -1,36 +1,93 @@
-INCLUDE_DIRECTORIES(
-${BULLET_PHYSICS_SOURCE_DIR}/src }
-)
-
-ADD_LIBRARY(LibBulletDynamics
+INCLUDE_DIRECTORIES( ${BULLET_PHYSICS_SOURCE_DIR}/src } )
+SET(BulletDynamics_SRCS
ConstraintSolver/btContactConstraint.cpp
- ConstraintSolver/btContactConstraint.h
ConstraintSolver/btConeTwistConstraint.cpp
- ConstraintSolver/btConeTwistConstraint.h
ConstraintSolver/btGeneric6DofConstraint.cpp
- ConstraintSolver/btGeneric6DofConstraint.h
ConstraintSolver/btHingeConstraint.cpp
- ConstraintSolver/btHingeConstraint.h
ConstraintSolver/btPoint2PointConstraint.cpp
- ConstraintSolver/btPoint2PointConstraint.h
ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
- ConstraintSolver/btSequentialImpulseConstraintSolver.h
ConstraintSolver/btSliderConstraint.cpp
- ConstraintSolver/btSliderConstraint.h
ConstraintSolver/btSolve2LinearConstraint.cpp
- ConstraintSolver/btSolve2LinearConstraint.h
ConstraintSolver/btTypedConstraint.cpp
- ConstraintSolver/btTypedConstraint.h
Dynamics/Bullet-C-API.cpp
Dynamics/btDiscreteDynamicsWorld.cpp
- Dynamics/btDiscreteDynamicsWorld.h
Dynamics/btSimpleDynamicsWorld.cpp
- Dynamics/btSimpleDynamicsWorld.h
Dynamics/btRigidBody.cpp
- Dynamics/btRigidBody.h
Vehicle/btRaycastVehicle.cpp
- Vehicle/btRaycastVehicle.h
Vehicle/btWheelInfo.cpp
+ Character/btKinematicCharacterController.cpp
+)
+
+SET(Root_HDRS
+ ../btBulletDynamicsCommon.h
+ ../btBulletCollisionCommon.h
+)
+SET(ConstraintSolver_HDRS
+ ConstraintSolver/btConstraintSolver.h
+ ConstraintSolver/btContactConstraint.h
+ ConstraintSolver/btContactSolverInfo.h
+ ConstraintSolver/btConeTwistConstraint.h
+ ConstraintSolver/btGeneric6DofConstraint.h
+ ConstraintSolver/btHingeConstraint.h
+ ConstraintSolver/btJacobianEntry.h
+ ConstraintSolver/btPoint2PointConstraint.h
+ ConstraintSolver/btSequentialImpulseConstraintSolver.h
+ ConstraintSolver/btSliderConstraint.h
+ ConstraintSolver/btSolve2LinearConstraint.h
+ ConstraintSolver/btSolverBody.h
+ ConstraintSolver/btSolverConstraint.h
+ ConstraintSolver/btTypedConstraint.h
+)
+SET(Dynamics_HDRS
+ Dynamics/btContinuousDynamicsWorld.h
+ Dynamics/btDiscreteDynamicsWorld.h
+ Dynamics/btDynamicsWorld.h
+ Dynamics/btSimpleDynamicsWorld.h
+ Dynamics/btRigidBody.h
+)
+SET(Vehicle_HDRS
+ Vehicle/btRaycastVehicle.h
+ Vehicle/btVehicleRaycaster.h
Vehicle/btWheelInfo.h
)
+
+SET(Character_HDRS
+ Character/btCharacterControllerInterface.h
+ Character/btKinematicCharacterController.h
+)
+
+
+
+SET(BulletDynamics_HDRS
+ ${Root_HDRS}
+ ${ConstraintSolver_HDRS}
+ ${Dynamics_HDRS}
+ ${Vehicle_HDRS}
+ ${Character_HDRS}
+)
+
+
+ADD_LIBRARY(BulletDynamics ${BulletDynamics_SRCS} ${BulletDynamics_HDRS})
+SET_TARGET_PROPERTIES(BulletDynamics PROPERTIES VERSION ${BULLET_VERSION})
+SET_TARGET_PROPERTIES(BulletDynamics PROPERTIES SOVERSION ${BULLET_VERSION})
+IF (BUILD_SHARED_LIBS)
+ TARGET_LINK_LIBRARIES(BulletDynamics BulletCollision LinearMath)
+ENDIF (BUILD_SHARED_LIBS)
+
+IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
+ INSTALL(TARGETS BulletDynamics DESTINATION lib)
+ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h")
+ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
+
+IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
+ SET_TARGET_PROPERTIES(BulletDynamics PROPERTIES FRAMEWORK true)
+
+ SET_TARGET_PROPERTIES(BulletDynamics PROPERTIES PUBLIC_HEADER "${Root_HDRS}")
+ # Have to list out sub-directories manually:
+ SET_PROPERTY(SOURCE ${ConstraintSolver_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/ConstraintSolver)
+ SET_PROPERTY(SOURCE ${Dynamics_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/Dynamics)
+ SET_PROPERTY(SOURCE ${Vehicle_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/Vehicle)
+ SET_PROPERTY(SOURCE ${Character_HDRS} PROPERTY MACOSX_PACKAGE_LOCATION Headers/Character)
+
+ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
index 61dad522a5b..29c8496c36f 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
@@ -22,8 +22,16 @@ Written by: Marcus Hennix
#include "LinearMath/btMinMax.h"
#include <new>
+//-----------------------------------------------------------------------------
+
+#define CONETWIST_USE_OBSOLETE_SOLVER false
+#define CONETWIST_DEF_FIX_THRESH btScalar(.05f)
+
+//-----------------------------------------------------------------------------
+
btConeTwistConstraint::btConeTwistConstraint()
-:btTypedConstraint(CONETWIST_CONSTRAINT_TYPE)
+:btTypedConstraint(CONETWIST_CONSTRAINT_TYPE),
+m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER)
{
}
@@ -31,69 +39,228 @@ btConeTwistConstraint::btConeTwistConstraint()
btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,
const btTransform& rbAFrame,const btTransform& rbBFrame)
:btTypedConstraint(CONETWIST_CONSTRAINT_TYPE, rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame),
- m_angularOnly(false)
+ m_angularOnly(false),
+ m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER)
{
- m_swingSpan1 = btScalar(1e30);
- m_swingSpan2 = btScalar(1e30);
- m_twistSpan = btScalar(1e30);
- m_biasFactor = 0.3f;
- m_relaxationFactor = 1.0f;
-
- m_solveTwistLimit = false;
- m_solveSwingLimit = false;
-
+ init();
}
btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame)
:btTypedConstraint(CONETWIST_CONSTRAINT_TYPE,rbA),m_rbAFrame(rbAFrame),
- m_angularOnly(false)
+ m_angularOnly(false),
+ m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER)
{
m_rbBFrame = m_rbAFrame;
-
- m_swingSpan1 = btScalar(1e30);
- m_swingSpan2 = btScalar(1e30);
- m_twistSpan = btScalar(1e30);
- m_biasFactor = 0.3f;
- m_relaxationFactor = 1.0f;
+ init();
+}
- m_solveTwistLimit = false;
- m_solveSwingLimit = false;
-
-}
-void btConeTwistConstraint::buildJacobian()
+void btConeTwistConstraint::init()
{
- m_appliedImpulse = btScalar(0.);
-
- //set bias, sign, clear accumulator
- m_swingCorrection = btScalar(0.);
- m_twistLimitSign = btScalar(0.);
+ m_angularOnly = false;
m_solveTwistLimit = false;
m_solveSwingLimit = false;
- m_accTwistLimitImpulse = btScalar(0.);
- m_accSwingLimitImpulse = btScalar(0.);
+ m_bMotorEnabled = false;
+ m_maxMotorImpulse = btScalar(-1);
+
+ setLimit(btScalar(1e30), btScalar(1e30), btScalar(1e30));
+ m_damping = btScalar(0.01);
+ m_fixThresh = CONETWIST_DEF_FIX_THRESH;
+}
- if (!m_angularOnly)
+
+//-----------------------------------------------------------------------------
+
+void btConeTwistConstraint::getInfo1 (btConstraintInfo1* info)
+{
+ if (m_useSolveConstraintObsolete)
{
- btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin();
- btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin();
- btVector3 relPos = pivotBInW - pivotAInW;
+ info->m_numConstraintRows = 0;
+ info->nub = 0;
+ }
+ else
+ {
+ info->m_numConstraintRows = 3;
+ info->nub = 3;
+ calcAngleInfo2();
+ if(m_solveSwingLimit)
+ {
+ info->m_numConstraintRows++;
+ info->nub--;
+ if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh))
+ {
+ info->m_numConstraintRows++;
+ info->nub--;
+ }
+ }
+ if(m_solveTwistLimit)
+ {
+ info->m_numConstraintRows++;
+ info->nub--;
+ }
+ }
+} // btConeTwistConstraint::getInfo1()
+
+//-----------------------------------------------------------------------------
- btVector3 normal[3];
- if (relPos.length2() > SIMD_EPSILON)
+void btConeTwistConstraint::getInfo2 (btConstraintInfo2* info)
+{
+ btAssert(!m_useSolveConstraintObsolete);
+ //retrieve matrices
+ btTransform body0_trans;
+ body0_trans = m_rbA.getCenterOfMassTransform();
+ btTransform body1_trans;
+ body1_trans = m_rbB.getCenterOfMassTransform();
+ // set jacobian
+ info->m_J1linearAxis[0] = 1;
+ info->m_J1linearAxis[info->rowskip+1] = 1;
+ info->m_J1linearAxis[2*info->rowskip+2] = 1;
+ btVector3 a1 = body0_trans.getBasis() * m_rbAFrame.getOrigin();
+ {
+ btVector3* angular0 = (btVector3*)(info->m_J1angularAxis);
+ btVector3* angular1 = (btVector3*)(info->m_J1angularAxis+info->rowskip);
+ btVector3* angular2 = (btVector3*)(info->m_J1angularAxis+2*info->rowskip);
+ btVector3 a1neg = -a1;
+ a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2);
+ }
+ btVector3 a2 = body1_trans.getBasis() * m_rbBFrame.getOrigin();
+ {
+ btVector3* angular0 = (btVector3*)(info->m_J2angularAxis);
+ btVector3* angular1 = (btVector3*)(info->m_J2angularAxis+info->rowskip);
+ btVector3* angular2 = (btVector3*)(info->m_J2angularAxis+2*info->rowskip);
+ a2.getSkewSymmetricMatrix(angular0,angular1,angular2);
+ }
+ // set right hand side
+ btScalar k = info->fps * info->erp;
+ int j;
+ for (j=0; j<3; j++)
+ {
+ info->m_constraintError[j*info->rowskip] = k * (a2[j] + body1_trans.getOrigin()[j] - a1[j] - body0_trans.getOrigin()[j]);
+ info->m_lowerLimit[j*info->rowskip] = -SIMD_INFINITY;
+ info->m_upperLimit[j*info->rowskip] = SIMD_INFINITY;
+ }
+ int row = 3;
+ int srow = row * info->rowskip;
+ btVector3 ax1;
+ // angular limits
+ if(m_solveSwingLimit)
+ {
+ btScalar *J1 = info->m_J1angularAxis;
+ btScalar *J2 = info->m_J2angularAxis;
+ if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh))
+ {
+ btTransform trA = m_rbA.getCenterOfMassTransform()*m_rbAFrame;
+ btVector3 p = trA.getBasis().getColumn(1);
+ btVector3 q = trA.getBasis().getColumn(2);
+ int srow1 = srow + info->rowskip;
+ J1[srow+0] = p[0];
+ J1[srow+1] = p[1];
+ J1[srow+2] = p[2];
+ J1[srow1+0] = q[0];
+ J1[srow1+1] = q[1];
+ J1[srow1+2] = q[2];
+ J2[srow+0] = -p[0];
+ J2[srow+1] = -p[1];
+ J2[srow+2] = -p[2];
+ J2[srow1+0] = -q[0];
+ J2[srow1+1] = -q[1];
+ J2[srow1+2] = -q[2];
+ btScalar fact = info->fps * m_relaxationFactor;
+ info->m_constraintError[srow] = fact * m_swingAxis.dot(p);
+ info->m_constraintError[srow1] = fact * m_swingAxis.dot(q);
+ info->m_lowerLimit[srow] = -SIMD_INFINITY;
+ info->m_upperLimit[srow] = SIMD_INFINITY;
+ info->m_lowerLimit[srow1] = -SIMD_INFINITY;
+ info->m_upperLimit[srow1] = SIMD_INFINITY;
+ srow = srow1 + info->rowskip;
+ }
+ else
+ {
+ ax1 = m_swingAxis * m_relaxationFactor * m_relaxationFactor;
+ J1[srow+0] = ax1[0];
+ J1[srow+1] = ax1[1];
+ J1[srow+2] = ax1[2];
+ J2[srow+0] = -ax1[0];
+ J2[srow+1] = -ax1[1];
+ J2[srow+2] = -ax1[2];
+ btScalar k = info->fps * m_biasFactor;
+
+ info->m_constraintError[srow] = k * m_swingCorrection;
+ info->cfm[srow] = 0.0f;
+ // m_swingCorrection is always positive or 0
+ info->m_lowerLimit[srow] = 0;
+ info->m_upperLimit[srow] = SIMD_INFINITY;
+ srow += info->rowskip;
+ }
+ }
+ if(m_solveTwistLimit)
+ {
+ ax1 = m_twistAxis * m_relaxationFactor * m_relaxationFactor;
+ btScalar *J1 = info->m_J1angularAxis;
+ btScalar *J2 = info->m_J2angularAxis;
+ J1[srow+0] = ax1[0];
+ J1[srow+1] = ax1[1];
+ J1[srow+2] = ax1[2];
+ J2[srow+0] = -ax1[0];
+ J2[srow+1] = -ax1[1];
+ J2[srow+2] = -ax1[2];
+ btScalar k = info->fps * m_biasFactor;
+ info->m_constraintError[srow] = k * m_twistCorrection;
+ info->cfm[srow] = 0.0f;
+ if(m_twistSpan > 0.0f)
{
- normal[0] = relPos.normalized();
+
+ if(m_twistCorrection > 0.0f)
+ {
+ info->m_lowerLimit[srow] = 0;
+ info->m_upperLimit[srow] = SIMD_INFINITY;
+ }
+ else
+ {
+ info->m_lowerLimit[srow] = -SIMD_INFINITY;
+ info->m_upperLimit[srow] = 0;
+ }
}
else
{
- normal[0].setValue(btScalar(1.0),0,0);
+ info->m_lowerLimit[srow] = -SIMD_INFINITY;
+ info->m_upperLimit[srow] = SIMD_INFINITY;
}
+ srow += info->rowskip;
+ }
+}
+
+//-----------------------------------------------------------------------------
- btPlaneSpace1(normal[0], normal[1], normal[2]);
+void btConeTwistConstraint::buildJacobian()
+{
+ if (m_useSolveConstraintObsolete)
+ {
+ m_appliedImpulse = btScalar(0.);
+ m_accTwistLimitImpulse = btScalar(0.);
+ m_accSwingLimitImpulse = btScalar(0.);
- for (int i=0;i<3;i++)
+ if (!m_angularOnly)
{
- new (&m_jac[i]) btJacobianEntry(
+ btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin();
+ btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin();
+ btVector3 relPos = pivotBInW - pivotAInW;
+
+ btVector3 normal[3];
+ if (relPos.length2() > SIMD_EPSILON)
+ {
+ normal[0] = relPos.normalized();
+ }
+ else
+ {
+ normal[0].setValue(btScalar(1.0),0,0);
+ }
+
+ btPlaneSpace1(normal[0], normal[1], normal[2]);
+
+ for (int i=0;i<3;i++)
+ {
+ new (&m_jac[i]) btJacobianEntry(
m_rbA.getCenterOfMassTransform().getBasis().transpose(),
m_rbB.getCenterOfMassTransform().getBasis().transpose(),
pivotAInW - m_rbA.getCenterOfMassPosition(),
@@ -103,9 +270,243 @@ void btConeTwistConstraint::buildJacobian()
m_rbA.getInvMass(),
m_rbB.getInvInertiaDiagLocal(),
m_rbB.getInvMass());
+ }
+ }
+
+ calcAngleInfo2();
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep)
+{
+ if (m_useSolveConstraintObsolete)
+ {
+ btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin();
+ btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin();
+
+ btScalar tau = btScalar(0.3);
+
+ //linear part
+ if (!m_angularOnly)
+ {
+ btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition();
+ btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
+
+ btVector3 vel1;
+ bodyA.getVelocityInLocalPointObsolete(rel_pos1,vel1);
+ btVector3 vel2;
+ bodyB.getVelocityInLocalPointObsolete(rel_pos2,vel2);
+ btVector3 vel = vel1 - vel2;
+
+ for (int i=0;i<3;i++)
+ {
+ const btVector3& normal = m_jac[i].m_linearJointAxis;
+ btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal();
+
+ btScalar rel_vel;
+ rel_vel = normal.dot(vel);
+ //positional error (zeroth order error)
+ btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal
+ btScalar impulse = depth*tau/timeStep * jacDiagABInv - rel_vel * jacDiagABInv;
+ m_appliedImpulse += impulse;
+
+ btVector3 ftorqueAxis1 = rel_pos1.cross(normal);
+ btVector3 ftorqueAxis2 = rel_pos2.cross(normal);
+ bodyA.applyImpulse(normal*m_rbA.getInvMass(), m_rbA.getInvInertiaTensorWorld()*ftorqueAxis1,impulse);
+ bodyB.applyImpulse(normal*m_rbB.getInvMass(), m_rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-impulse);
+
+ }
+ }
+
+ // apply motor
+ if (m_bMotorEnabled)
+ {
+ // compute current and predicted transforms
+ btTransform trACur = m_rbA.getCenterOfMassTransform();
+ btTransform trBCur = m_rbB.getCenterOfMassTransform();
+ btVector3 omegaA; bodyA.getAngularVelocity(omegaA);
+ btVector3 omegaB; bodyB.getAngularVelocity(omegaB);
+ btTransform trAPred; trAPred.setIdentity();
+ btVector3 zerovec(0,0,0);
+ btTransformUtil::integrateTransform(
+ trACur, zerovec, omegaA, timeStep, trAPred);
+ btTransform trBPred; trBPred.setIdentity();
+ btTransformUtil::integrateTransform(
+ trBCur, zerovec, omegaB, timeStep, trBPred);
+
+ // compute desired transforms in world
+ btTransform trPose(m_qTarget);
+ btTransform trABDes = m_rbBFrame * trPose * m_rbAFrame.inverse();
+ btTransform trADes = trBPred * trABDes;
+ btTransform trBDes = trAPred * trABDes.inverse();
+
+ // compute desired omegas in world
+ btVector3 omegaADes, omegaBDes;
+
+ btTransformUtil::calculateVelocity(trACur, trADes, timeStep, zerovec, omegaADes);
+ btTransformUtil::calculateVelocity(trBCur, trBDes, timeStep, zerovec, omegaBDes);
+
+ // compute delta omegas
+ btVector3 dOmegaA = omegaADes - omegaA;
+ btVector3 dOmegaB = omegaBDes - omegaB;
+
+ // compute weighted avg axis of dOmega (weighting based on inertias)
+ btVector3 axisA, axisB;
+ btScalar kAxisAInv = 0, kAxisBInv = 0;
+
+ if (dOmegaA.length2() > SIMD_EPSILON)
+ {
+ axisA = dOmegaA.normalized();
+ kAxisAInv = getRigidBodyA().computeAngularImpulseDenominator(axisA);
+ }
+
+ if (dOmegaB.length2() > SIMD_EPSILON)
+ {
+ axisB = dOmegaB.normalized();
+ kAxisBInv = getRigidBodyB().computeAngularImpulseDenominator(axisB);
+ }
+
+ btVector3 avgAxis = kAxisAInv * axisA + kAxisBInv * axisB;
+
+ static bool bDoTorque = true;
+ if (bDoTorque && avgAxis.length2() > SIMD_EPSILON)
+ {
+ avgAxis.normalize();
+ kAxisAInv = getRigidBodyA().computeAngularImpulseDenominator(avgAxis);
+ kAxisBInv = getRigidBodyB().computeAngularImpulseDenominator(avgAxis);
+ btScalar kInvCombined = kAxisAInv + kAxisBInv;
+
+ btVector3 impulse = (kAxisAInv * dOmegaA - kAxisBInv * dOmegaB) /
+ (kInvCombined * kInvCombined);
+
+ if (m_maxMotorImpulse >= 0)
+ {
+ btScalar fMaxImpulse = m_maxMotorImpulse;
+ if (m_bNormalizedMotorStrength)
+ fMaxImpulse = fMaxImpulse/kAxisAInv;
+
+ btVector3 newUnclampedAccImpulse = m_accMotorImpulse + impulse;
+ btScalar newUnclampedMag = newUnclampedAccImpulse.length();
+ if (newUnclampedMag > fMaxImpulse)
+ {
+ newUnclampedAccImpulse.normalize();
+ newUnclampedAccImpulse *= fMaxImpulse;
+ impulse = newUnclampedAccImpulse - m_accMotorImpulse;
+ }
+ m_accMotorImpulse += impulse;
+ }
+
+ btScalar impulseMag = impulse.length();
+ btVector3 impulseAxis = impulse / impulseMag;
+
+ bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*impulseAxis, impulseMag);
+ bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*impulseAxis, -impulseMag);
+
+ }
+ }
+ else // no motor: do a little damping
+ {
+ const btVector3& angVelA = getRigidBodyA().getAngularVelocity();
+ const btVector3& angVelB = getRigidBodyB().getAngularVelocity();
+ btVector3 relVel = angVelB - angVelA;
+ if (relVel.length2() > SIMD_EPSILON)
+ {
+ btVector3 relVelAxis = relVel.normalized();
+ btScalar m_kDamping = btScalar(1.) /
+ (getRigidBodyA().computeAngularImpulseDenominator(relVelAxis) +
+ getRigidBodyB().computeAngularImpulseDenominator(relVelAxis));
+ btVector3 impulse = m_damping * m_kDamping * relVel;
+
+ btScalar impulseMag = impulse.length();
+ btVector3 impulseAxis = impulse / impulseMag;
+ bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*impulseAxis, impulseMag);
+ bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*impulseAxis, -impulseMag);
+ }
+ }
+
+ // joint limits
+ {
+ ///solve angular part
+ btVector3 angVelA;
+ bodyA.getAngularVelocity(angVelA);
+ btVector3 angVelB;
+ bodyB.getAngularVelocity(angVelB);
+
+ // solve swing limit
+ if (m_solveSwingLimit)
+ {
+ btScalar amplitude = m_swingLimitRatio * m_swingCorrection*m_biasFactor/timeStep;
+ btScalar relSwingVel = (angVelB - angVelA).dot(m_swingAxis);
+ if (relSwingVel > 0)
+ amplitude += m_swingLimitRatio * relSwingVel * m_relaxationFactor;
+ btScalar impulseMag = amplitude * m_kSwing;
+
+ // Clamp the accumulated impulse
+ btScalar temp = m_accSwingLimitImpulse;
+ m_accSwingLimitImpulse = btMax(m_accSwingLimitImpulse + impulseMag, btScalar(0.0) );
+ impulseMag = m_accSwingLimitImpulse - temp;
+
+ btVector3 impulse = m_swingAxis * impulseMag;
+
+ // don't let cone response affect twist
+ // (this can happen since body A's twist doesn't match body B's AND we use an elliptical cone limit)
+ {
+ btVector3 impulseTwistCouple = impulse.dot(m_twistAxisA) * m_twistAxisA;
+ btVector3 impulseNoTwistCouple = impulse - impulseTwistCouple;
+ impulse = impulseNoTwistCouple;
+ }
+
+ impulseMag = impulse.length();
+ btVector3 noTwistSwingAxis = impulse / impulseMag;
+
+ bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*noTwistSwingAxis, impulseMag);
+ bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*noTwistSwingAxis, -impulseMag);
+ }
+
+
+ // solve twist limit
+ if (m_solveTwistLimit)
+ {
+ btScalar amplitude = m_twistLimitRatio * m_twistCorrection*m_biasFactor/timeStep;
+ btScalar relTwistVel = (angVelB - angVelA).dot( m_twistAxis );
+ if (relTwistVel > 0) // only damp when moving towards limit (m_twistAxis flipping is important)
+ amplitude += m_twistLimitRatio * relTwistVel * m_relaxationFactor;
+ btScalar impulseMag = amplitude * m_kTwist;
+
+ // Clamp the accumulated impulse
+ btScalar temp = m_accTwistLimitImpulse;
+ m_accTwistLimitImpulse = btMax(m_accTwistLimitImpulse + impulseMag, btScalar(0.0) );
+ impulseMag = m_accTwistLimitImpulse - temp;
+
+ btVector3 impulse = m_twistAxis * impulseMag;
+
+ bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*m_twistAxis,impulseMag);
+ bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*m_twistAxis,-impulseMag);
+ }
}
}
+}
+
+//-----------------------------------------------------------------------------
+
+void btConeTwistConstraint::updateRHS(btScalar timeStep)
+{
+ (void)timeStep;
+
+}
+
+//-----------------------------------------------------------------------------
+
+void btConeTwistConstraint::calcAngleInfo()
+{
+ m_swingCorrection = btScalar(0.);
+ m_twistLimitSign = btScalar(0.);
+ m_solveTwistLimit = false;
+ m_solveSwingLimit = false;
+
btVector3 b1Axis1,b1Axis2,b1Axis3;
btVector3 b2Axis1,b2Axis2;
@@ -122,20 +523,17 @@ void btConeTwistConstraint::buildJacobian()
if (m_swingSpan1 >= btScalar(0.05f))
{
b1Axis2 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(1);
-// swing1 = btAtan2Fast( b2Axis1.dot(b1Axis2),b2Axis1.dot(b1Axis1) );
swx = b2Axis1.dot(b1Axis1);
swy = b2Axis1.dot(b1Axis2);
swing1 = btAtan2Fast(swy, swx);
fact = (swy*swy + swx*swx) * thresh * thresh;
fact = fact / (fact + btScalar(1.0));
swing1 *= fact;
-
}
if (m_swingSpan2 >= btScalar(0.05f))
{
b1Axis3 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(2);
-// swing2 = btAtan2Fast( b2Axis1.dot(b1Axis3),b2Axis1.dot(b1Axis1) );
swx = b2Axis1.dot(b1Axis1);
swy = b2Axis1.dot(b1Axis3);
swing2 = btAtan2Fast(swy, swx);
@@ -152,17 +550,11 @@ void btConeTwistConstraint::buildJacobian()
{
m_swingCorrection = EllipseAngle-1.0f;
m_solveSwingLimit = true;
-
// Calculate necessary axis & factors
m_swingAxis = b2Axis1.cross(b1Axis2* b2Axis1.dot(b1Axis2) + b1Axis3* b2Axis1.dot(b1Axis3));
m_swingAxis.normalize();
-
btScalar swingAxisSign = (b2Axis1.dot(b1Axis1) >= 0.0f) ? 1.0f : -1.0f;
m_swingAxis *= swingAxisSign;
-
- m_kSwing = btScalar(1.) / (getRigidBodyA().computeAngularImpulseDenominator(m_swingAxis) +
- getRigidBodyB().computeAngularImpulseDenominator(m_swingAxis));
-
}
// Twist limits
@@ -172,118 +564,426 @@ void btConeTwistConstraint::buildJacobian()
btQuaternion rotationArc = shortestArcQuat(b2Axis1,b1Axis1);
btVector3 TwistRef = quatRotate(rotationArc,b2Axis2);
btScalar twist = btAtan2Fast( TwistRef.dot(b1Axis3), TwistRef.dot(b1Axis2) );
+ m_twistAngle = twist;
- btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? m_limitSoftness : btScalar(0.);
+// btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? m_limitSoftness : btScalar(0.);
+ btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? btScalar(1.0f) : btScalar(0.);
if (twist <= -m_twistSpan*lockedFreeFactor)
{
m_twistCorrection = -(twist + m_twistSpan);
m_solveTwistLimit = true;
-
m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f;
m_twistAxis.normalize();
m_twistAxis *= -1.0f;
+ }
+ else if (twist > m_twistSpan*lockedFreeFactor)
+ {
+ m_twistCorrection = (twist - m_twistSpan);
+ m_solveTwistLimit = true;
+ m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f;
+ m_twistAxis.normalize();
+ }
+ }
+} // btConeTwistConstraint::calcAngleInfo()
+
+
+static btVector3 vTwist(1,0,0); // twist axis in constraint's space
+
+//-----------------------------------------------------------------------------
+
+void btConeTwistConstraint::calcAngleInfo2()
+{
+ m_swingCorrection = btScalar(0.);
+ m_twistLimitSign = btScalar(0.);
+ m_solveTwistLimit = false;
+ m_solveSwingLimit = false;
+
+ {
+ // compute rotation of A wrt B (in constraint space)
+ btQuaternion qA = getRigidBodyA().getCenterOfMassTransform().getRotation() * m_rbAFrame.getRotation();
+ btQuaternion qB = getRigidBodyB().getCenterOfMassTransform().getRotation() * m_rbBFrame.getRotation();
+ btQuaternion qAB = qB.inverse() * qA;
+
+ // split rotation into cone and twist
+ // (all this is done from B's perspective. Maybe I should be averaging axes...)
+ btVector3 vConeNoTwist = quatRotate(qAB, vTwist); vConeNoTwist.normalize();
+ btQuaternion qABCone = shortestArcQuat(vTwist, vConeNoTwist); qABCone.normalize();
+ btQuaternion qABTwist = qABCone.inverse() * qAB; qABTwist.normalize();
+
+ if (m_swingSpan1 >= m_fixThresh && m_swingSpan2 >= m_fixThresh)
+ {
+ btScalar swingAngle, swingLimit = 0; btVector3 swingAxis;
+ computeConeLimitInfo(qABCone, swingAngle, swingAxis, swingLimit);
+
+ if (swingAngle > swingLimit * m_limitSoftness)
+ {
+ m_solveSwingLimit = true;
+
+ // compute limit ratio: 0->1, where
+ // 0 == beginning of soft limit
+ // 1 == hard/real limit
+ m_swingLimitRatio = 1.f;
+ if (swingAngle < swingLimit && m_limitSoftness < 1.f - SIMD_EPSILON)
+ {
+ m_swingLimitRatio = (swingAngle - swingLimit * m_limitSoftness)/
+ (swingLimit - swingLimit * m_limitSoftness);
+ }
+
+ // swing correction tries to get back to soft limit
+ m_swingCorrection = swingAngle - (swingLimit * m_limitSoftness);
+
+ // adjustment of swing axis (based on ellipse normal)
+ adjustSwingAxisToUseEllipseNormal(swingAxis);
+
+ // Calculate necessary axis & factors
+ m_swingAxis = quatRotate(qB, -swingAxis);
+
+ m_twistAxisA.setValue(0,0,0);
+
+ m_kSwing = btScalar(1.) /
+ (getRigidBodyA().computeAngularImpulseDenominator(m_swingAxis) +
+ getRigidBodyB().computeAngularImpulseDenominator(m_swingAxis));
+ }
+ }
+ else
+ {
+ // you haven't set any limits;
+ // or you're trying to set at least one of the swing limits too small. (if so, do you really want a conetwist constraint?)
+ // anyway, we have either hinge or fixed joint
+ btVector3 ivA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(0);
+ btVector3 jvA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(1);
+ btVector3 kvA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2);
+ btVector3 ivB = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_rbBFrame.getBasis().getColumn(0);
+ btVector3 target;
+ btScalar x = ivB.dot(ivA);
+ btScalar y = ivB.dot(jvA);
+ btScalar z = ivB.dot(kvA);
+ if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh))
+ { // fixed. We'll need to add one more row to constraint
+ if((!btFuzzyZero(y)) || (!(btFuzzyZero(z))))
+ {
+ m_solveSwingLimit = true;
+ m_swingAxis = -ivB.cross(ivA);
+ }
+ }
+ else
+ {
+ if(m_swingSpan1 < m_fixThresh)
+ { // hinge around Y axis
+ if(!(btFuzzyZero(y)))
+ {
+ m_solveSwingLimit = true;
+ if(m_swingSpan2 >= m_fixThresh)
+ {
+ y = btScalar(0.f);
+ btScalar span2 = btAtan2(z, x);
+ if(span2 > m_swingSpan2)
+ {
+ x = btCos(m_swingSpan2);
+ z = btSin(m_swingSpan2);
+ }
+ else if(span2 < -m_swingSpan2)
+ {
+ x = btCos(m_swingSpan2);
+ z = -btSin(m_swingSpan2);
+ }
+ }
+ }
+ }
+ else
+ { // hinge around Z axis
+ if(!btFuzzyZero(z))
+ {
+ m_solveSwingLimit = true;
+ if(m_swingSpan1 >= m_fixThresh)
+ {
+ z = btScalar(0.f);
+ btScalar span1 = btAtan2(y, x);
+ if(span1 > m_swingSpan1)
+ {
+ x = btCos(m_swingSpan1);
+ y = btSin(m_swingSpan1);
+ }
+ else if(span1 < -m_swingSpan1)
+ {
+ x = btCos(m_swingSpan1);
+ y = -btSin(m_swingSpan1);
+ }
+ }
+ }
+ }
+ target[0] = x * ivA[0] + y * jvA[0] + z * kvA[0];
+ target[1] = x * ivA[1] + y * jvA[1] + z * kvA[1];
+ target[2] = x * ivA[2] + y * jvA[2] + z * kvA[2];
+ target.normalize();
+ m_swingAxis = -ivB.cross(target);
+ m_swingCorrection = m_swingAxis.length();
+ m_swingAxis.normalize();
+ }
+ }
- m_kTwist = btScalar(1.) / (getRigidBodyA().computeAngularImpulseDenominator(m_twistAxis) +
- getRigidBodyB().computeAngularImpulseDenominator(m_twistAxis));
+ if (m_twistSpan >= btScalar(0.f))
+ {
+ btVector3 twistAxis;
+ computeTwistLimitInfo(qABTwist, m_twistAngle, twistAxis);
- } else
- if (twist > m_twistSpan*lockedFreeFactor)
+ if (m_twistAngle > m_twistSpan*m_limitSoftness)
{
- m_twistCorrection = (twist - m_twistSpan);
m_solveTwistLimit = true;
- m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f;
- m_twistAxis.normalize();
+ m_twistLimitRatio = 1.f;
+ if (m_twistAngle < m_twistSpan && m_limitSoftness < 1.f - SIMD_EPSILON)
+ {
+ m_twistLimitRatio = (m_twistAngle - m_twistSpan * m_limitSoftness)/
+ (m_twistSpan - m_twistSpan * m_limitSoftness);
+ }
- m_kTwist = btScalar(1.) / (getRigidBodyA().computeAngularImpulseDenominator(m_twistAxis) +
- getRigidBodyB().computeAngularImpulseDenominator(m_twistAxis));
+ // twist correction tries to get back to soft limit
+ m_twistCorrection = m_twistAngle - (m_twistSpan * m_limitSoftness);
+ m_twistAxis = quatRotate(qB, -twistAxis);
+
+ m_kTwist = btScalar(1.) /
+ (getRigidBodyA().computeAngularImpulseDenominator(m_twistAxis) +
+ getRigidBodyB().computeAngularImpulseDenominator(m_twistAxis));
}
+
+ if (m_solveSwingLimit)
+ m_twistAxisA = quatRotate(qA, -twistAxis);
+ }
+ else
+ {
+ m_twistAngle = btScalar(0.f);
+ }
+ }
+} // btConeTwistConstraint::calcAngleInfo2()
+
+
+
+// given a cone rotation in constraint space, (pre: twist must already be removed)
+// this method computes its corresponding swing angle and axis.
+// more interestingly, it computes the cone/swing limit (angle) for this cone "pose".
+void btConeTwistConstraint::computeConeLimitInfo(const btQuaternion& qCone,
+ btScalar& swingAngle, // out
+ btVector3& vSwingAxis, // out
+ btScalar& swingLimit) // out
+{
+ swingAngle = qCone.getAngle();
+ if (swingAngle > SIMD_EPSILON)
+ {
+ vSwingAxis = btVector3(qCone.x(), qCone.y(), qCone.z());
+ vSwingAxis.normalize();
+ if (fabs(vSwingAxis.x()) > SIMD_EPSILON)
+ {
+ // non-zero twist?! this should never happen.
+ int wtf = 0; wtf = wtf;
+ }
+
+ // Compute limit for given swing. tricky:
+ // Given a swing axis, we're looking for the intersection with the bounding cone ellipse.
+ // (Since we're dealing with angles, this ellipse is embedded on the surface of a sphere.)
+
+ // For starters, compute the direction from center to surface of ellipse.
+ // This is just the perpendicular (ie. rotate 2D vector by PI/2) of the swing axis.
+ // (vSwingAxis is the cone rotation (in z,y); change vars and rotate to (x,y) coords.)
+ btScalar xEllipse = vSwingAxis.y();
+ btScalar yEllipse = -vSwingAxis.z();
+
+ // Now, we use the slope of the vector (using x/yEllipse) and find the length
+ // of the line that intersects the ellipse:
+ // x^2 y^2
+ // --- + --- = 1, where a and b are semi-major axes 2 and 1 respectively (ie. the limits)
+ // a^2 b^2
+ // Do the math and it should be clear.
+
+ swingLimit = m_swingSpan1; // if xEllipse == 0, we have a pure vSwingAxis.z rotation: just use swingspan1
+ if (fabs(xEllipse) > SIMD_EPSILON)
+ {
+ btScalar surfaceSlope2 = (yEllipse*yEllipse)/(xEllipse*xEllipse);
+ btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2);
+ norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1);
+ btScalar swingLimit2 = (1 + surfaceSlope2) / norm;
+ swingLimit = sqrt(swingLimit2);
+ }
+
+ // test!
+ /*swingLimit = m_swingSpan2;
+ if (fabs(vSwingAxis.z()) > SIMD_EPSILON)
+ {
+ btScalar mag_2 = m_swingSpan1*m_swingSpan1 + m_swingSpan2*m_swingSpan2;
+ btScalar sinphi = m_swingSpan2 / sqrt(mag_2);
+ btScalar phi = asin(sinphi);
+ btScalar theta = atan2(fabs(vSwingAxis.y()),fabs(vSwingAxis.z()));
+ btScalar alpha = 3.14159f - theta - phi;
+ btScalar sinalpha = sin(alpha);
+ swingLimit = m_swingSpan1 * sinphi/sinalpha;
+ }*/
+ }
+ else if (swingAngle < 0)
+ {
+ // this should never happen!
+ int wtf = 0; wtf = wtf;
}
}
-void btConeTwistConstraint::solveConstraint(btScalar timeStep)
+btVector3 btConeTwistConstraint::GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const
{
+ // compute x/y in ellipse using cone angle (0 -> 2*PI along surface of cone)
+ btScalar xEllipse = btCos(fAngleInRadians);
+ btScalar yEllipse = btSin(fAngleInRadians);
+
+ // Use the slope of the vector (using x/yEllipse) and find the length
+ // of the line that intersects the ellipse:
+ // x^2 y^2
+ // --- + --- = 1, where a and b are semi-major axes 2 and 1 respectively (ie. the limits)
+ // a^2 b^2
+ // Do the math and it should be clear.
+
+ float swingLimit = m_swingSpan1; // if xEllipse == 0, just use axis b (1)
+ if (fabs(xEllipse) > SIMD_EPSILON)
+ {
+ btScalar surfaceSlope2 = (yEllipse*yEllipse)/(xEllipse*xEllipse);
+ btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2);
+ norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1);
+ btScalar swingLimit2 = (1 + surfaceSlope2) / norm;
+ swingLimit = sqrt(swingLimit2);
+ }
- btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin();
- btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin();
+ // convert into point in constraint space:
+ // note: twist is x-axis, swing 1 and 2 are along the z and y axes respectively
+ btVector3 vSwingAxis(0, xEllipse, -yEllipse);
+ btQuaternion qSwing(vSwingAxis, swingLimit);
+ btVector3 vPointInConstraintSpace(fLength,0,0);
+ return quatRotate(qSwing, vPointInConstraintSpace);
+}
- btScalar tau = btScalar(0.3);
+// given a twist rotation in constraint space, (pre: cone must already be removed)
+// this method computes its corresponding angle and axis.
+void btConeTwistConstraint::computeTwistLimitInfo(const btQuaternion& qTwist,
+ btScalar& twistAngle, // out
+ btVector3& vTwistAxis) // out
+{
+ btQuaternion qMinTwist = qTwist;
+ twistAngle = qTwist.getAngle();
- //linear part
- if (!m_angularOnly)
+ if (twistAngle > SIMD_PI) // long way around. flip quat and recalculate.
{
- btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition();
- btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
-
- btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1);
- btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2);
- btVector3 vel = vel1 - vel2;
-
- for (int i=0;i<3;i++)
- {
- const btVector3& normal = m_jac[i].m_linearJointAxis;
- btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal();
-
- btScalar rel_vel;
- rel_vel = normal.dot(vel);
- //positional error (zeroth order error)
- btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal
- btScalar impulse = depth*tau/timeStep * jacDiagABInv - rel_vel * jacDiagABInv;
- m_appliedImpulse += impulse;
- btVector3 impulse_vector = normal * impulse;
- m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition());
- m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition());
- }
+ qMinTwist = operator-(qTwist);
+ twistAngle = qMinTwist.getAngle();
}
-
+ if (twistAngle < 0)
{
- ///solve angular part
- const btVector3& angVelA = getRigidBodyA().getAngularVelocity();
- const btVector3& angVelB = getRigidBodyB().getAngularVelocity();
+ // this should never happen
+ int wtf = 0; wtf = wtf;
+ }
- // solve swing limit
- if (m_solveSwingLimit)
- {
- btScalar amplitude = ((angVelB - angVelA).dot( m_swingAxis )*m_relaxationFactor*m_relaxationFactor + m_swingCorrection*(btScalar(1.)/timeStep)*m_biasFactor);
- btScalar impulseMag = amplitude * m_kSwing;
+ vTwistAxis = btVector3(qMinTwist.x(), qMinTwist.y(), qMinTwist.z());
+ if (twistAngle > SIMD_EPSILON)
+ vTwistAxis.normalize();
+}
- // Clamp the accumulated impulse
- btScalar temp = m_accSwingLimitImpulse;
- m_accSwingLimitImpulse = btMax(m_accSwingLimitImpulse + impulseMag, btScalar(0.0) );
- impulseMag = m_accSwingLimitImpulse - temp;
- btVector3 impulse = m_swingAxis * impulseMag;
+void btConeTwistConstraint::adjustSwingAxisToUseEllipseNormal(btVector3& vSwingAxis) const
+{
+ // the swing axis is computed as the "twist-free" cone rotation,
+ // but the cone limit is not circular, but elliptical (if swingspan1 != swingspan2).
+ // so, if we're outside the limits, the closest way back inside the cone isn't
+ // along the vector back to the center. better (and more stable) to use the ellipse normal.
+
+ // convert swing axis to direction from center to surface of ellipse
+ // (ie. rotate 2D vector by PI/2)
+ btScalar y = -vSwingAxis.z();
+ btScalar z = vSwingAxis.y();
+
+ // do the math...
+ if (fabs(z) > SIMD_EPSILON) // avoid division by 0. and we don't need an update if z == 0.
+ {
+ // compute gradient/normal of ellipse surface at current "point"
+ btScalar grad = y/z;
+ grad *= m_swingSpan2 / m_swingSpan1;
- m_rbA.applyTorqueImpulse(impulse);
- m_rbB.applyTorqueImpulse(-impulse);
+ // adjust y/z to represent normal at point (instead of vector to point)
+ if (y > 0)
+ y = fabs(grad * z);
+ else
+ y = -fabs(grad * z);
- }
+ // convert ellipse direction back to swing axis
+ vSwingAxis.setZ(-y);
+ vSwingAxis.setY( z);
+ vSwingAxis.normalize();
+ }
+}
+
+
+
+void btConeTwistConstraint::setMotorTarget(const btQuaternion &q)
+{
+ btTransform trACur = m_rbA.getCenterOfMassTransform();
+ btTransform trBCur = m_rbB.getCenterOfMassTransform();
+ btTransform trABCur = trBCur.inverse() * trACur;
+ btQuaternion qABCur = trABCur.getRotation();
+ btTransform trConstraintCur = (trBCur * m_rbBFrame).inverse() * (trACur * m_rbAFrame);
+ btQuaternion qConstraintCur = trConstraintCur.getRotation();
+
+ btQuaternion qConstraint = m_rbBFrame.getRotation().inverse() * q * m_rbAFrame.getRotation();
+ setMotorTargetInConstraintSpace(qConstraint);
+}
- // solve twist limit
- if (m_solveTwistLimit)
- {
- btScalar amplitude = ((angVelB - angVelA).dot( m_twistAxis )*m_relaxationFactor*m_relaxationFactor + m_twistCorrection*(btScalar(1.)/timeStep)*m_biasFactor );
- btScalar impulseMag = amplitude * m_kTwist;
- // Clamp the accumulated impulse
- btScalar temp = m_accTwistLimitImpulse;
- m_accTwistLimitImpulse = btMax(m_accTwistLimitImpulse + impulseMag, btScalar(0.0) );
- impulseMag = m_accTwistLimitImpulse - temp;
+void btConeTwistConstraint::setMotorTargetInConstraintSpace(const btQuaternion &q)
+{
+ m_qTarget = q;
+
+ // clamp motor target to within limits
+ {
+ btScalar softness = 1.f;//m_limitSoftness;
- btVector3 impulse = m_twistAxis * impulseMag;
+ // split into twist and cone
+ btVector3 vTwisted = quatRotate(m_qTarget, vTwist);
+ btQuaternion qTargetCone = shortestArcQuat(vTwist, vTwisted); qTargetCone.normalize();
+ btQuaternion qTargetTwist = qTargetCone.inverse() * m_qTarget; qTargetTwist.normalize();
- m_rbA.applyTorqueImpulse(impulse);
- m_rbB.applyTorqueImpulse(-impulse);
+ // clamp cone
+ if (m_swingSpan1 >= btScalar(0.05f) && m_swingSpan2 >= btScalar(0.05f))
+ {
+ btScalar swingAngle, swingLimit; btVector3 swingAxis;
+ computeConeLimitInfo(qTargetCone, swingAngle, swingAxis, swingLimit);
+ if (fabs(swingAngle) > SIMD_EPSILON)
+ {
+ if (swingAngle > swingLimit*softness)
+ swingAngle = swingLimit*softness;
+ else if (swingAngle < -swingLimit*softness)
+ swingAngle = -swingLimit*softness;
+ qTargetCone = btQuaternion(swingAxis, swingAngle);
+ }
}
-
- }
-}
+ // clamp twist
+ if (m_twistSpan >= btScalar(0.05f))
+ {
+ btScalar twistAngle; btVector3 twistAxis;
+ computeTwistLimitInfo(qTargetTwist, twistAngle, twistAxis);
-void btConeTwistConstraint::updateRHS(btScalar timeStep)
-{
- (void)timeStep;
+ if (fabs(twistAngle) > SIMD_EPSILON)
+ {
+ // eddy todo: limitSoftness used here???
+ if (twistAngle > m_twistSpan*softness)
+ twistAngle = m_twistSpan*softness;
+ else if (twistAngle < -m_twistSpan*softness)
+ twistAngle = -m_twistSpan*softness;
+ qTargetTwist = btQuaternion(twistAxis, twistAngle);
+ }
+ }
+ m_qTarget = qTargetCone * qTargetTwist;
+ }
}
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
index f121919c8f9..84ea9e04095 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
@@ -20,7 +20,7 @@ Written by: Marcus Hennix
#ifndef CONETWISTCONSTRAINT_H
#define CONETWISTCONSTRAINT_H
-#include "../../LinearMath/btVector3.h"
+#include "LinearMath/btVector3.h"
#include "btJacobianEntry.h"
#include "btTypedConstraint.h"
@@ -42,10 +42,14 @@ public:
btScalar m_biasFactor;
btScalar m_relaxationFactor;
+ btScalar m_damping;
+
btScalar m_swingSpan1;
btScalar m_swingSpan2;
btScalar m_twistSpan;
+ btScalar m_fixThresh;
+
btVector3 m_swingAxis;
btVector3 m_twistAxis;
@@ -56,6 +60,8 @@ public:
btScalar m_swingCorrection;
btScalar m_twistCorrection;
+ btScalar m_twistAngle;
+
btScalar m_accSwingLimitImpulse;
btScalar m_accTwistLimitImpulse;
@@ -63,6 +69,19 @@ public:
bool m_solveTwistLimit;
bool m_solveSwingLimit;
+ bool m_useSolveConstraintObsolete;
+
+ // not yet used...
+ btScalar m_swingLimitRatio;
+ btScalar m_twistLimitRatio;
+ btVector3 m_twistAxisA;
+
+ // motor
+ bool m_bMotorEnabled;
+ bool m_bNormalizedMotorStrength;
+ btQuaternion m_qTarget;
+ btScalar m_maxMotorImpulse;
+ btVector3 m_accMotorImpulse;
public:
@@ -74,7 +93,12 @@ public:
virtual void buildJacobian();
- virtual void solveConstraint(btScalar timeStep);
+ virtual void getInfo1 (btConstraintInfo1* info);
+
+ virtual void getInfo2 (btConstraintInfo2* info);
+
+
+ virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep);
void updateRHS(btScalar timeStep);
@@ -92,7 +116,32 @@ public:
m_angularOnly = angularOnly;
}
- void setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 0.8f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
+ void setLimit(int limitIndex,btScalar limitValue)
+ {
+ switch (limitIndex)
+ {
+ case 3:
+ {
+ m_twistSpan = limitValue;
+ break;
+ }
+ case 4:
+ {
+ m_swingSpan2 = limitValue;
+ break;
+ }
+ case 5:
+ {
+ m_swingSpan1 = limitValue;
+ break;
+ }
+ default:
+ {
+ }
+ };
+ }
+
+ void setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
{
m_swingSpan1 = _swingSpan1;
m_swingSpan2 = _swingSpan2;
@@ -121,6 +170,60 @@ public:
return m_twistLimitSign;
}
+ void calcAngleInfo();
+ void calcAngleInfo2();
+
+ inline btScalar getSwingSpan1()
+ {
+ return m_swingSpan1;
+ }
+ inline btScalar getSwingSpan2()
+ {
+ return m_swingSpan2;
+ }
+ inline btScalar getTwistSpan()
+ {
+ return m_twistSpan;
+ }
+ inline btScalar getTwistAngle()
+ {
+ return m_twistAngle;
+ }
+ bool isPastSwingLimit() { return m_solveSwingLimit; }
+
+
+ void setDamping(btScalar damping) { m_damping = damping; }
+
+ void enableMotor(bool b) { m_bMotorEnabled = b; }
+ void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = false; }
+ void setMaxMotorImpulseNormalized(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = true; }
+
+ btScalar getFixThresh() { return m_fixThresh; }
+ void setFixThresh(btScalar fixThresh) { m_fixThresh = fixThresh; }
+
+ // setMotorTarget:
+ // q: the desired rotation of bodyA wrt bodyB.
+ // note: if q violates the joint limits, the internal target is clamped to avoid conflicting impulses (very bad for stability)
+ // note: don't forget to enableMotor()
+ void setMotorTarget(const btQuaternion &q);
+
+ // same as above, but q is the desired rotation of frameA wrt frameB in constraint space
+ void setMotorTargetInConstraintSpace(const btQuaternion &q);
+
+ btVector3 GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const;
+
+
+
+protected:
+ void init();
+
+ void computeConeLimitInfo(const btQuaternion& qCone, // in
+ btScalar& swingAngle, btVector3& vSwingAxis, btScalar& swingLimit); // all outs
+
+ void computeTwistLimitInfo(const btQuaternion& qTwist, // in
+ btScalar& twistAngle, btVector3& vTwistAxis); // all outs
+
+ void adjustSwingAxisToUseEllipseNormal(btVector3& vSwingAxis) const;
};
#endif //CONETWISTCONSTRAINT_H
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
index 4d7cd05feb7..012c321fd6d 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
@@ -22,7 +22,7 @@ subject to the following restrictions:
#include "LinearMath/btMinMax.h"
#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h"
-#define ASSERT2 assert
+#define ASSERT2 btAssert
#define USE_INTERNAL_APPLY_IMPULSE 1
@@ -52,7 +52,7 @@ void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1,
btVector3 vel = vel1 - vel2;
- btJacobianEntry jac(body1.getCenterOfMassTransform().getBasis().transpose(),
+ btJacobianEntry jac(body1.getCenterOfMassTransform().getBasis().transpose(),
body2.getCenterOfMassTransform().getBasis().transpose(),
rel_pos1,rel_pos2,normal,body1.getInvInertiaDiagLocal(),body1.getInvMass(),
body2.getInvInertiaDiagLocal(),body2.getInvMass());
@@ -114,7 +114,7 @@ btScalar resolveSingleCollision(
btScalar Kcor = Kerp *Kfps;
btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData;
- assert(cpd);
+ btAssert(cpd);
btScalar distance = cpd->m_penetration;
btScalar positionalError = Kcor *-distance;
btScalar velocityError = cpd->m_restitution - rel_vel;// * damping;
@@ -166,7 +166,7 @@ btScalar resolveSingleFriction(
btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition();
btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData;
- assert(cpd);
+ btAssert(cpd);
btScalar combinedFriction = cpd->m_friction;
@@ -255,7 +255,7 @@ btScalar resolveSingleFrictionOriginal(
btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition();
btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData;
- assert(cpd);
+ btAssert(cpd);
btScalar combinedFriction = cpd->m_friction;
@@ -337,7 +337,7 @@ btScalar resolveSingleCollisionCombined(
btScalar Kcor = Kerp *Kfps;
btConstraintPersistentData* cpd = (btConstraintPersistentData*) contactPoint.m_userPersistentData;
- assert(cpd);
+ btAssert(cpd);
btScalar distance = cpd->m_penetration;
btScalar positionalError = Kcor *-distance;
btScalar velocityError = cpd->m_restitution - rel_vel;// * damping;
@@ -425,5 +425,5 @@ btScalar resolveSingleFrictionEmpty(
return btScalar(0.);
-};
+}
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h
index 826e79f78bd..e8871f3860b 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.h
@@ -16,7 +16,7 @@ subject to the following restrictions:
#ifndef CONTACT_CONSTRAINT_H
#define CONTACT_CONSTRAINT_H
-//todo: make into a proper class working with the iterative constraint solver
+///@todo: make into a proper class working with the iterative constraint solver
class btRigidBody;
#include "LinearMath/btVector3.h"
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
index 916d4581f79..e99430c00de 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
@@ -21,7 +21,13 @@ enum btSolverMode
SOLVER_RANDMIZE_ORDER = 1,
SOLVER_FRICTION_SEPARATE = 2,
SOLVER_USE_WARMSTARTING = 4,
- SOLVER_CACHE_FRIENDLY = 8
+ SOLVER_USE_FRICTION_WARMSTARTING = 8,
+ SOLVER_USE_2_FRICTION_DIRECTIONS = 16,
+ SOLVER_ENABLE_FRICTION_DIRECTION_CACHING = 32,
+ SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION = 64,
+ SOLVER_CACHE_FRIENDLY = 128,
+ SOLVER_SIMD = 256, //enabled for Windows, the solver innerloop is branchless SIMD, 40% faster than FPU/scalar version
+ SOLVER_CUDA = 512 //will be open sourced during Game Developers Conference 2009. Much faster.
};
struct btContactSolverInfoData
@@ -38,12 +44,14 @@ struct btContactSolverInfoData
btScalar m_sor;
btScalar m_erp;//used as Baumgarte factor
btScalar m_erp2;//used in Split Impulse
+ btScalar m_globalCfm;//constraint force mixing
int m_splitImpulse;
btScalar m_splitImpulsePenetrationThreshold;
btScalar m_linearSlop;
btScalar m_warmstartingFactor;
int m_solverMode;
+ int m_restingContactRestitutionThreshold;
};
@@ -63,12 +71,14 @@ struct btContactSolverInfo : public btContactSolverInfoData
m_numIterations = 10;
m_erp = btScalar(0.2);
m_erp2 = btScalar(0.1);
- m_sor = btScalar(1.3);
+ m_globalCfm = btScalar(0.);
+ m_sor = btScalar(1.);
m_splitImpulse = false;
m_splitImpulsePenetrationThreshold = -0.02f;
m_linearSlop = btScalar(0.0);
m_warmstartingFactor=btScalar(0.85);
- m_solverMode = SOLVER_RANDMIZE_ORDER | SOLVER_CACHE_FRIENDLY | SOLVER_USE_WARMSTARTING;
+ m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD ;//SOLVER_RANDMIZE_ORDER
+ m_restingContactRestitutionThreshold = 2;//resting contact lifetime threshold to disable restitution
}
};
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
index 077b326d13a..6cbfe61f700 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
@@ -19,18 +19,40 @@ email: projectileman@yahoo.com
http://gimpact.sf.net
*/
-
#include "btGeneric6DofConstraint.h"
#include "BulletDynamics/Dynamics/btRigidBody.h"
#include "LinearMath/btTransformUtil.h"
#include <new>
-static const btScalar kSign[] = { btScalar(1.0), btScalar(-1.0), btScalar(1.0) };
-static const int kAxisA[] = { 1, 0, 0 };
-static const int kAxisB[] = { 2, 2, 1 };
+#define D6_USE_OBSOLETE_METHOD false
+//-----------------------------------------------------------------------------
+
+btGeneric6DofConstraint::btGeneric6DofConstraint()
+:btTypedConstraint(D6_CONSTRAINT_TYPE),
+m_useLinearReferenceFrameA(true),
+m_useSolveConstraintObsolete(D6_USE_OBSOLETE_METHOD)
+{
+}
+
+//-----------------------------------------------------------------------------
+
+btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA)
+: btTypedConstraint(D6_CONSTRAINT_TYPE, rbA, rbB)
+, m_frameInA(frameInA)
+, m_frameInB(frameInB),
+m_useLinearReferenceFrameA(useLinearReferenceFrameA),
+m_useSolveConstraintObsolete(D6_USE_OBSOLETE_METHOD)
+{
+
+}
+//-----------------------------------------------------------------------------
+
+
#define GENERIC_D6_DISABLE_WARMSTARTING 1
+//-----------------------------------------------------------------------------
+
btScalar btGetMatrixElem(const btMatrix3x3& mat, int index);
btScalar btGetMatrixElem(const btMatrix3x3& mat, int index)
{
@@ -39,51 +61,48 @@ btScalar btGetMatrixElem(const btMatrix3x3& mat, int index)
return mat[i][j];
}
+//-----------------------------------------------------------------------------
+
///MatrixToEulerXYZ from http://www.geometrictools.com/LibFoundation/Mathematics/Wm4Matrix3.inl.html
bool matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz);
bool matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz)
{
-// // rot = cy*cz -cy*sz sy
-// // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx
-// // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy
-//
+ // // rot = cy*cz -cy*sz sy
+ // // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx
+ // // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy
+ //
- if (btGetMatrixElem(mat,2) < btScalar(1.0))
+ btScalar fi = btGetMatrixElem(mat,2);
+ if (fi < btScalar(1.0f))
+ {
+ if (fi > btScalar(-1.0f))
{
- if (btGetMatrixElem(mat,2) > btScalar(-1.0))
- {
- xyz[0] = btAtan2(-btGetMatrixElem(mat,5),btGetMatrixElem(mat,8));
- xyz[1] = btAsin(btGetMatrixElem(mat,2));
- xyz[2] = btAtan2(-btGetMatrixElem(mat,1),btGetMatrixElem(mat,0));
- return true;
- }
- else
- {
- // WARNING. Not unique. XA - ZA = -atan2(r10,r11)
- xyz[0] = -btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4));
- xyz[1] = -SIMD_HALF_PI;
- xyz[2] = btScalar(0.0);
- return false;
- }
+ xyz[0] = btAtan2(-btGetMatrixElem(mat,5),btGetMatrixElem(mat,8));
+ xyz[1] = btAsin(btGetMatrixElem(mat,2));
+ xyz[2] = btAtan2(-btGetMatrixElem(mat,1),btGetMatrixElem(mat,0));
+ return true;
}
else
{
- // WARNING. Not unique. XAngle + ZAngle = atan2(r10,r11)
- xyz[0] = btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4));
- xyz[1] = SIMD_HALF_PI;
- xyz[2] = 0.0;
-
+ // WARNING. Not unique. XA - ZA = -atan2(r10,r11)
+ xyz[0] = -btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4));
+ xyz[1] = -SIMD_HALF_PI;
+ xyz[2] = btScalar(0.0);
+ return false;
}
-
-
+ }
+ else
+ {
+ // WARNING. Not unique. XAngle + ZAngle = atan2(r10,r11)
+ xyz[0] = btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4));
+ xyz[1] = SIMD_HALF_PI;
+ xyz[2] = 0.0;
+ }
return false;
}
-
-
//////////////////////////// btRotationalLimitMotor ////////////////////////////////////
-
int btRotationalLimitMotor::testLimitValue(btScalar test_value)
{
if(m_loLimit>m_hiLimit)
@@ -107,212 +126,239 @@ int btRotationalLimitMotor::testLimitValue(btScalar test_value)
m_currentLimit = 0;//Free from violation
return 0;
-
+
}
+//-----------------------------------------------------------------------------
btScalar btRotationalLimitMotor::solveAngularLimits(
- btScalar timeStep,btVector3& axis,btScalar jacDiagABInv,
- btRigidBody * body0, btRigidBody * body1)
+ btScalar timeStep,btVector3& axis,btScalar jacDiagABInv,
+ btRigidBody * body0, btSolverBody& bodyA, btRigidBody * body1, btSolverBody& bodyB)
{
- if (needApplyTorques()==false) return 0.0f;
+ if (needApplyTorques()==false) return 0.0f;
- btScalar target_velocity = m_targetVelocity;
- btScalar maxMotorForce = m_maxMotorForce;
+ btScalar target_velocity = m_targetVelocity;
+ btScalar maxMotorForce = m_maxMotorForce;
//current error correction
- if (m_currentLimit!=0)
- {
- target_velocity = -m_ERP*m_currentLimitError/(timeStep);
- maxMotorForce = m_maxLimitForce;
- }
+ if (m_currentLimit!=0)
+ {
+ target_velocity = -m_ERP*m_currentLimitError/(timeStep);
+ maxMotorForce = m_maxLimitForce;
+ }
- maxMotorForce *= timeStep;
+ maxMotorForce *= timeStep;
- // current velocity difference
- btVector3 vel_diff = body0->getAngularVelocity();
- if (body1)
- {
- vel_diff -= body1->getAngularVelocity();
- }
+ // current velocity difference
+ btVector3 angVelA;
+ bodyA.getAngularVelocity(angVelA);
+ btVector3 angVelB;
+ bodyB.getAngularVelocity(angVelB);
+ btVector3 vel_diff;
+ vel_diff = angVelA-angVelB;
- btScalar rel_vel = axis.dot(vel_diff);
+
+
+ btScalar rel_vel = axis.dot(vel_diff);
// correction velocity
- btScalar motor_relvel = m_limitSoftness*(target_velocity - m_damping*rel_vel);
+ btScalar motor_relvel = m_limitSoftness*(target_velocity - m_damping*rel_vel);
- if ( motor_relvel < SIMD_EPSILON && motor_relvel > -SIMD_EPSILON )
- {
- return 0.0f;//no need for applying force
- }
+ if ( motor_relvel < SIMD_EPSILON && motor_relvel > -SIMD_EPSILON )
+ {
+ return 0.0f;//no need for applying force
+ }
// correction impulse
- btScalar unclippedMotorImpulse = (1+m_bounce)*motor_relvel*jacDiagABInv;
+ btScalar unclippedMotorImpulse = (1+m_bounce)*motor_relvel*jacDiagABInv;
// clip correction impulse
- btScalar clippedMotorImpulse;
+ btScalar clippedMotorImpulse;
- //todo: should clip against accumulated impulse
- if (unclippedMotorImpulse>0.0f)
- {
- clippedMotorImpulse = unclippedMotorImpulse > maxMotorForce? maxMotorForce: unclippedMotorImpulse;
- }
- else
- {
- clippedMotorImpulse = unclippedMotorImpulse < -maxMotorForce ? -maxMotorForce: unclippedMotorImpulse;
- }
+ ///@todo: should clip against accumulated impulse
+ if (unclippedMotorImpulse>0.0f)
+ {
+ clippedMotorImpulse = unclippedMotorImpulse > maxMotorForce? maxMotorForce: unclippedMotorImpulse;
+ }
+ else
+ {
+ clippedMotorImpulse = unclippedMotorImpulse < -maxMotorForce ? -maxMotorForce: unclippedMotorImpulse;
+ }
// sort with accumulated impulses
- btScalar lo = btScalar(-1e30);
- btScalar hi = btScalar(1e30);
-
- btScalar oldaccumImpulse = m_accumulatedImpulse;
- btScalar sum = oldaccumImpulse + clippedMotorImpulse;
- m_accumulatedImpulse = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum;
+ btScalar lo = btScalar(-1e30);
+ btScalar hi = btScalar(1e30);
- clippedMotorImpulse = m_accumulatedImpulse - oldaccumImpulse;
+ btScalar oldaccumImpulse = m_accumulatedImpulse;
+ btScalar sum = oldaccumImpulse + clippedMotorImpulse;
+ m_accumulatedImpulse = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum;
+ clippedMotorImpulse = m_accumulatedImpulse - oldaccumImpulse;
+ btVector3 motorImp = clippedMotorImpulse * axis;
- btVector3 motorImp = clippedMotorImpulse * axis;
+ //body0->applyTorqueImpulse(motorImp);
+ //body1->applyTorqueImpulse(-motorImp);
+ bodyA.applyImpulse(btVector3(0,0,0), body0->getInvInertiaTensorWorld()*axis,clippedMotorImpulse);
+ bodyB.applyImpulse(btVector3(0,0,0), body1->getInvInertiaTensorWorld()*axis,-clippedMotorImpulse);
- body0->applyTorqueImpulse(motorImp);
- if (body1) body1->applyTorqueImpulse(-motorImp);
- return clippedMotorImpulse;
+ return clippedMotorImpulse;
}
//////////////////////////// End btRotationalLimitMotor ////////////////////////////////////
+
+
+
//////////////////////////// btTranslationalLimitMotor ////////////////////////////////////
-btScalar btTranslationalLimitMotor::solveLinearAxis(
- btScalar timeStep,
- btScalar jacDiagABInv,
- btRigidBody& body1,const btVector3 &pointInA,
- btRigidBody& body2,const btVector3 &pointInB,
- int limit_index,
- const btVector3 & axis_normal_on_a,
- const btVector3 & anchorPos)
+
+
+int btTranslationalLimitMotor::testLimitValue(int limitIndex, btScalar test_value)
{
+ btScalar loLimit = m_lowerLimit[limitIndex];
+ btScalar hiLimit = m_upperLimit[limitIndex];
+ if(loLimit > hiLimit)
+ {
+ m_currentLimit[limitIndex] = 0;//Free from violation
+ m_currentLimitError[limitIndex] = btScalar(0.f);
+ return 0;
+ }
-///find relative velocity
-// btVector3 rel_pos1 = pointInA - body1.getCenterOfMassPosition();
-// btVector3 rel_pos2 = pointInB - body2.getCenterOfMassPosition();
- btVector3 rel_pos1 = anchorPos - body1.getCenterOfMassPosition();
- btVector3 rel_pos2 = anchorPos - body2.getCenterOfMassPosition();
+ if (test_value < loLimit)
+ {
+ m_currentLimit[limitIndex] = 2;//low limit violation
+ m_currentLimitError[limitIndex] = test_value - loLimit;
+ return 2;
+ }
+ else if (test_value> hiLimit)
+ {
+ m_currentLimit[limitIndex] = 1;//High limit violation
+ m_currentLimitError[limitIndex] = test_value - hiLimit;
+ return 1;
+ };
- btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
- btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
- btVector3 vel = vel1 - vel2;
+ m_currentLimit[limitIndex] = 0;//Free from violation
+ m_currentLimitError[limitIndex] = btScalar(0.f);
+ return 0;
+} // btTranslationalLimitMotor::testLimitValue()
- btScalar rel_vel = axis_normal_on_a.dot(vel);
+//-----------------------------------------------------------------------------
+btScalar btTranslationalLimitMotor::solveLinearAxis(
+ btScalar timeStep,
+ btScalar jacDiagABInv,
+ btRigidBody& body1,btSolverBody& bodyA,const btVector3 &pointInA,
+ btRigidBody& body2,btSolverBody& bodyB,const btVector3 &pointInB,
+ int limit_index,
+ const btVector3 & axis_normal_on_a,
+ const btVector3 & anchorPos)
+{
+ ///find relative velocity
+ // btVector3 rel_pos1 = pointInA - body1.getCenterOfMassPosition();
+ // btVector3 rel_pos2 = pointInB - body2.getCenterOfMassPosition();
+ btVector3 rel_pos1 = anchorPos - body1.getCenterOfMassPosition();
+ btVector3 rel_pos2 = anchorPos - body2.getCenterOfMassPosition();
-/// apply displacement correction
+ btVector3 vel1;
+ bodyA.getVelocityInLocalPointObsolete(rel_pos1,vel1);
+ btVector3 vel2;
+ bodyB.getVelocityInLocalPointObsolete(rel_pos2,vel2);
+ btVector3 vel = vel1 - vel2;
-//positional error (zeroth order error)
- btScalar depth = -(pointInA - pointInB).dot(axis_normal_on_a);
- btScalar lo = btScalar(-1e30);
- btScalar hi = btScalar(1e30);
+ btScalar rel_vel = axis_normal_on_a.dot(vel);
- btScalar minLimit = m_lowerLimit[limit_index];
- btScalar maxLimit = m_upperLimit[limit_index];
- //handle the limits
- if (minLimit < maxLimit)
- {
- {
- if (depth > maxLimit)
- {
- depth -= maxLimit;
- lo = btScalar(0.);
- }
- else
- {
- if (depth < minLimit)
- {
- depth -= minLimit;
- hi = btScalar(0.);
- }
- else
- {
- return 0.0f;
- }
- }
- }
- }
+ /// apply displacement correction
- btScalar normalImpulse= m_limitSoftness*(m_restitution*depth/timeStep - m_damping*rel_vel) * jacDiagABInv;
+ //positional error (zeroth order error)
+ btScalar depth = -(pointInA - pointInB).dot(axis_normal_on_a);
+ btScalar lo = btScalar(-1e30);
+ btScalar hi = btScalar(1e30);
+ btScalar minLimit = m_lowerLimit[limit_index];
+ btScalar maxLimit = m_upperLimit[limit_index];
+ //handle the limits
+ if (minLimit < maxLimit)
+ {
+ {
+ if (depth > maxLimit)
+ {
+ depth -= maxLimit;
+ lo = btScalar(0.);
+
+ }
+ else
+ {
+ if (depth < minLimit)
+ {
+ depth -= minLimit;
+ hi = btScalar(0.);
+ }
+ else
+ {
+ return 0.0f;
+ }
+ }
+ }
+ }
+ btScalar normalImpulse= m_limitSoftness*(m_restitution*depth/timeStep - m_damping*rel_vel) * jacDiagABInv;
- btScalar oldNormalImpulse = m_accumulatedImpulse[limit_index];
- btScalar sum = oldNormalImpulse + normalImpulse;
- m_accumulatedImpulse[limit_index] = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum;
- normalImpulse = m_accumulatedImpulse[limit_index] - oldNormalImpulse;
- btVector3 impulse_vector = axis_normal_on_a * normalImpulse;
- body1.applyImpulse( impulse_vector, rel_pos1);
- body2.applyImpulse(-impulse_vector, rel_pos2);
- return normalImpulse;
-}
-//////////////////////////// btTranslationalLimitMotor ////////////////////////////////////
+ btScalar oldNormalImpulse = m_accumulatedImpulse[limit_index];
+ btScalar sum = oldNormalImpulse + normalImpulse;
+ m_accumulatedImpulse[limit_index] = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum;
+ normalImpulse = m_accumulatedImpulse[limit_index] - oldNormalImpulse;
-btGeneric6DofConstraint::btGeneric6DofConstraint()
- :btTypedConstraint(D6_CONSTRAINT_TYPE),
- m_useLinearReferenceFrameA(true)
-{
-}
+ btVector3 impulse_vector = axis_normal_on_a * normalImpulse;
+ //body1.applyImpulse( impulse_vector, rel_pos1);
+ //body2.applyImpulse(-impulse_vector, rel_pos2);
-btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA)
- : btTypedConstraint(D6_CONSTRAINT_TYPE, rbA, rbB)
- , m_frameInA(frameInA)
- , m_frameInB(frameInB),
- m_useLinearReferenceFrameA(useLinearReferenceFrameA)
-{
+ btVector3 ftorqueAxis1 = rel_pos1.cross(axis_normal_on_a);
+ btVector3 ftorqueAxis2 = rel_pos2.cross(axis_normal_on_a);
+ bodyA.applyImpulse(axis_normal_on_a*body1.getInvMass(), body1.getInvInertiaTensorWorld()*ftorqueAxis1,normalImpulse);
+ bodyB.applyImpulse(axis_normal_on_a*body2.getInvMass(), body2.getInvInertiaTensorWorld()*ftorqueAxis2,-normalImpulse);
-}
+ return normalImpulse;
+}
+//////////////////////////// btTranslationalLimitMotor ////////////////////////////////////
void btGeneric6DofConstraint::calculateAngleInfo()
{
btMatrix3x3 relative_frame = m_calculatedTransformA.getBasis().inverse()*m_calculatedTransformB.getBasis();
-
matrixToEulerXYZ(relative_frame,m_calculatedAxisAngleDiff);
-
-
-
// in euler angle mode we do not actually constrain the angular velocity
- // along the axes axis[0] and axis[2] (although we do use axis[1]) :
- //
- // to get constrain w2-w1 along ...not
- // ------ --------------------- ------
- // d(angle[0])/dt = 0 ax[1] x ax[2] ax[0]
- // d(angle[1])/dt = 0 ax[1]
- // d(angle[2])/dt = 0 ax[0] x ax[1] ax[2]
- //
- // constraining w2-w1 along an axis 'a' means that a'*(w2-w1)=0.
- // to prove the result for angle[0], write the expression for angle[0] from
- // GetInfo1 then take the derivative. to prove this for angle[2] it is
- // easier to take the euler rate expression for d(angle[2])/dt with respect
- // to the components of w and set that to 0.
-
+ // along the axes axis[0] and axis[2] (although we do use axis[1]) :
+ //
+ // to get constrain w2-w1 along ...not
+ // ------ --------------------- ------
+ // d(angle[0])/dt = 0 ax[1] x ax[2] ax[0]
+ // d(angle[1])/dt = 0 ax[1]
+ // d(angle[2])/dt = 0 ax[0] x ax[1] ax[2]
+ //
+ // constraining w2-w1 along an axis 'a' means that a'*(w2-w1)=0.
+ // to prove the result for angle[0], write the expression for angle[0] from
+ // GetInfo1 then take the derivative. to prove this for angle[2] it is
+ // easier to take the euler rate expression for d(angle[2])/dt with respect
+ // to the components of w and set that to 0.
btVector3 axis0 = m_calculatedTransformB.getBasis().getColumn(0);
btVector3 axis2 = m_calculatedTransformA.getBasis().getColumn(2);
@@ -320,34 +366,29 @@ void btGeneric6DofConstraint::calculateAngleInfo()
m_calculatedAxis[0] = m_calculatedAxis[1].cross(axis2);
m_calculatedAxis[2] = axis0.cross(m_calculatedAxis[1]);
-
-// if(m_debugDrawer)
-// {
-//
-// char buff[300];
-// sprintf(buff,"\n X: %.2f ; Y: %.2f ; Z: %.2f ",
-// m_calculatedAxisAngleDiff[0],
-// m_calculatedAxisAngleDiff[1],
-// m_calculatedAxisAngleDiff[2]);
-// m_debugDrawer->reportErrorWarning(buff);
-// }
+ m_calculatedAxis[0].normalize();
+ m_calculatedAxis[1].normalize();
+ m_calculatedAxis[2].normalize();
}
+//-----------------------------------------------------------------------------
+
void btGeneric6DofConstraint::calculateTransforms()
{
- m_calculatedTransformA = m_rbA.getCenterOfMassTransform() * m_frameInA;
- m_calculatedTransformB = m_rbB.getCenterOfMassTransform() * m_frameInB;
-
- calculateAngleInfo();
+ m_calculatedTransformA = m_rbA.getCenterOfMassTransform() * m_frameInA;
+ m_calculatedTransformB = m_rbB.getCenterOfMassTransform() * m_frameInB;
+ calculateLinearInfo();
+ calculateAngleInfo();
}
+//-----------------------------------------------------------------------------
void btGeneric6DofConstraint::buildLinearJacobian(
- btJacobianEntry & jacLinear,const btVector3 & normalWorld,
- const btVector3 & pivotAInW,const btVector3 & pivotBInW)
+ btJacobianEntry & jacLinear,const btVector3 & normalWorld,
+ const btVector3 & pivotAInW,const btVector3 & pivotBInW)
{
- new (&jacLinear) btJacobianEntry(
+ new (&jacLinear) btJacobianEntry(
m_rbA.getCenterOfMassTransform().getBasis().transpose(),
m_rbB.getCenterOfMassTransform().getBasis().transpose(),
pivotAInW - m_rbA.getCenterOfMassPosition(),
@@ -357,13 +398,14 @@ void btGeneric6DofConstraint::buildLinearJacobian(
m_rbA.getInvMass(),
m_rbB.getInvInertiaDiagLocal(),
m_rbB.getInvMass());
-
}
+//-----------------------------------------------------------------------------
+
void btGeneric6DofConstraint::buildAngularJacobian(
- btJacobianEntry & jacAngular,const btVector3 & jointAxisW)
+ btJacobianEntry & jacAngular,const btVector3 & jointAxisW)
{
- new (&jacAngular) btJacobianEntry(jointAxisW,
+ new (&jacAngular) btJacobianEntry(jointAxisW,
m_rbA.getCenterOfMassTransform().getBasis().transpose(),
m_rbB.getCenterOfMassTransform().getBasis().transpose(),
m_rbA.getInvInertiaDiagLocal(),
@@ -371,142 +413,260 @@ void btGeneric6DofConstraint::buildAngularJacobian(
}
+//-----------------------------------------------------------------------------
+
bool btGeneric6DofConstraint::testAngularLimitMotor(int axis_index)
{
- btScalar angle = m_calculatedAxisAngleDiff[axis_index];
-
- //test limits
- m_angularLimits[axis_index].testLimitValue(angle);
- return m_angularLimits[axis_index].needApplyTorques();
+ btScalar angle = m_calculatedAxisAngleDiff[axis_index];
+ //test limits
+ m_angularLimits[axis_index].testLimitValue(angle);
+ return m_angularLimits[axis_index].needApplyTorques();
}
+//-----------------------------------------------------------------------------
+
void btGeneric6DofConstraint::buildJacobian()
{
+ if (m_useSolveConstraintObsolete)
+ {
- // Clear accumulated impulses for the next simulation step
- m_linearLimits.m_accumulatedImpulse.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
- int i;
- for(i = 0; i < 3; i++)
- {
- m_angularLimits[i].m_accumulatedImpulse = btScalar(0.);
- }
- //calculates transform
- calculateTransforms();
-
-// const btVector3& pivotAInW = m_calculatedTransformA.getOrigin();
-// const btVector3& pivotBInW = m_calculatedTransformB.getOrigin();
- calcAnchorPos();
- btVector3 pivotAInW = m_AnchorPos;
- btVector3 pivotBInW = m_AnchorPos;
-
-// not used here
-// btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition();
-// btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
-
- btVector3 normalWorld;
- //linear part
- for (i=0;i<3;i++)
- {
- if (m_linearLimits.isLimited(i))
- {
- if (m_useLinearReferenceFrameA)
- normalWorld = m_calculatedTransformA.getBasis().getColumn(i);
- else
- normalWorld = m_calculatedTransformB.getBasis().getColumn(i);
+ // Clear accumulated impulses for the next simulation step
+ m_linearLimits.m_accumulatedImpulse.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
+ int i;
+ for(i = 0; i < 3; i++)
+ {
+ m_angularLimits[i].m_accumulatedImpulse = btScalar(0.);
+ }
+ //calculates transform
+ calculateTransforms();
+
+ // const btVector3& pivotAInW = m_calculatedTransformA.getOrigin();
+ // const btVector3& pivotBInW = m_calculatedTransformB.getOrigin();
+ calcAnchorPos();
+ btVector3 pivotAInW = m_AnchorPos;
+ btVector3 pivotBInW = m_AnchorPos;
+
+ // not used here
+ // btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition();
+ // btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
+
+ btVector3 normalWorld;
+ //linear part
+ for (i=0;i<3;i++)
+ {
+ if (m_linearLimits.isLimited(i))
+ {
+ if (m_useLinearReferenceFrameA)
+ normalWorld = m_calculatedTransformA.getBasis().getColumn(i);
+ else
+ normalWorld = m_calculatedTransformB.getBasis().getColumn(i);
- buildLinearJacobian(
- m_jacLinear[i],normalWorld ,
- pivotAInW,pivotBInW);
+ buildLinearJacobian(
+ m_jacLinear[i],normalWorld ,
+ pivotAInW,pivotBInW);
- }
- }
+ }
+ }
- // angular part
- for (i=0;i<3;i++)
- {
- //calculates error angle
- if (testAngularLimitMotor(i))
- {
- normalWorld = this->getAxis(i);
- // Create angular atom
- buildAngularJacobian(m_jacAng[i],normalWorld);
- }
- }
+ // angular part
+ for (i=0;i<3;i++)
+ {
+ //calculates error angle
+ if (testAngularLimitMotor(i))
+ {
+ normalWorld = this->getAxis(i);
+ // Create angular atom
+ buildAngularJacobian(m_jacAng[i],normalWorld);
+ }
+ }
+
+ }
+}
+//-----------------------------------------------------------------------------
+void btGeneric6DofConstraint::getInfo1 (btConstraintInfo1* info)
+{
+ if (m_useSolveConstraintObsolete)
+ {
+ info->m_numConstraintRows = 0;
+ info->nub = 0;
+ } else
+ {
+ //prepare constraint
+ calculateTransforms();
+ info->m_numConstraintRows = 0;
+ info->nub = 6;
+ int i;
+ //test linear limits
+ for(i = 0; i < 3; i++)
+ {
+ if(m_linearLimits.needApplyForce(i))
+ {
+ info->m_numConstraintRows++;
+ info->nub--;
+ }
+ }
+ //test angular limits
+ for (i=0;i<3 ;i++ )
+ {
+ if(testAngularLimitMotor(i))
+ {
+ info->m_numConstraintRows++;
+ info->nub--;
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+void btGeneric6DofConstraint::getInfo2 (btConstraintInfo2* info)
+{
+ btAssert(!m_useSolveConstraintObsolete);
+ int row = setLinearLimits(info);
+ setAngularLimits(info, row);
}
+//-----------------------------------------------------------------------------
-void btGeneric6DofConstraint::solveConstraint(btScalar timeStep)
+int btGeneric6DofConstraint::setLinearLimits(btConstraintInfo2* info)
{
- m_timeStep = timeStep;
+ btGeneric6DofConstraint * d6constraint = this;
+ int row = 0;
+ //solve linear limits
+ btRotationalLimitMotor limot;
+ for (int i=0;i<3 ;i++ )
+ {
+ if(m_linearLimits.needApplyForce(i))
+ { // re-use rotational motor code
+ limot.m_bounce = btScalar(0.f);
+ limot.m_currentLimit = m_linearLimits.m_currentLimit[i];
+ limot.m_currentLimitError = m_linearLimits.m_currentLimitError[i];
+ limot.m_damping = m_linearLimits.m_damping;
+ limot.m_enableMotor = m_linearLimits.m_enableMotor[i];
+ limot.m_ERP = m_linearLimits.m_restitution;
+ limot.m_hiLimit = m_linearLimits.m_upperLimit[i];
+ limot.m_limitSoftness = m_linearLimits.m_limitSoftness;
+ limot.m_loLimit = m_linearLimits.m_lowerLimit[i];
+ limot.m_maxLimitForce = btScalar(0.f);
+ limot.m_maxMotorForce = m_linearLimits.m_maxMotorForce[i];
+ limot.m_targetVelocity = m_linearLimits.m_targetVelocity[i];
+ btVector3 axis = m_calculatedTransformA.getBasis().getColumn(i);
+ row += get_limit_motor_info2(&limot, &m_rbA, &m_rbB, info, row, axis, 0);
+ }
+ }
+ return row;
+}
- //calculateTransforms();
+//-----------------------------------------------------------------------------
- int i;
+int btGeneric6DofConstraint::setAngularLimits(btConstraintInfo2 *info, int row_offset)
+{
+ btGeneric6DofConstraint * d6constraint = this;
+ int row = row_offset;
+ //solve angular limits
+ for (int i=0;i<3 ;i++ )
+ {
+ if(d6constraint->getRotationalLimitMotor(i)->needApplyTorques())
+ {
+ btVector3 axis = d6constraint->getAxis(i);
+ row += get_limit_motor_info2(
+ d6constraint->getRotationalLimitMotor(i),
+ &m_rbA,
+ &m_rbB,
+ info,row,axis,1);
+ }
+ }
- // linear
+ return row;
+}
- btVector3 pointInA = m_calculatedTransformA.getOrigin();
- btVector3 pointInB = m_calculatedTransformB.getOrigin();
+//-----------------------------------------------------------------------------
- btScalar jacDiagABInv;
- btVector3 linear_axis;
- for (i=0;i<3;i++)
- {
- if (m_linearLimits.isLimited(i))
- {
- jacDiagABInv = btScalar(1.) / m_jacLinear[i].getDiagonal();
+void btGeneric6DofConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep)
+{
+ if (m_useSolveConstraintObsolete)
+ {
- if (m_useLinearReferenceFrameA)
- linear_axis = m_calculatedTransformA.getBasis().getColumn(i);
- else
- linear_axis = m_calculatedTransformB.getBasis().getColumn(i);
- m_linearLimits.solveLinearAxis(
- m_timeStep,
- jacDiagABInv,
- m_rbA,pointInA,
- m_rbB,pointInB,
- i,linear_axis, m_AnchorPos);
+ m_timeStep = timeStep;
- }
- }
+ //calculateTransforms();
- // angular
- btVector3 angular_axis;
- btScalar angularJacDiagABInv;
- for (i=0;i<3;i++)
- {
- if (m_angularLimits[i].needApplyTorques())
- {
+ int i;
- // get axis
- angular_axis = getAxis(i);
+ // linear
- angularJacDiagABInv = btScalar(1.) / m_jacAng[i].getDiagonal();
+ btVector3 pointInA = m_calculatedTransformA.getOrigin();
+ btVector3 pointInB = m_calculatedTransformB.getOrigin();
- m_angularLimits[i].solveAngularLimits(m_timeStep,angular_axis,angularJacDiagABInv, &m_rbA,&m_rbB);
- }
- }
+ btScalar jacDiagABInv;
+ btVector3 linear_axis;
+ for (i=0;i<3;i++)
+ {
+ if (m_linearLimits.isLimited(i))
+ {
+ jacDiagABInv = btScalar(1.) / m_jacLinear[i].getDiagonal();
+
+ if (m_useLinearReferenceFrameA)
+ linear_axis = m_calculatedTransformA.getBasis().getColumn(i);
+ else
+ linear_axis = m_calculatedTransformB.getBasis().getColumn(i);
+
+ m_linearLimits.solveLinearAxis(
+ m_timeStep,
+ jacDiagABInv,
+ m_rbA,bodyA,pointInA,
+ m_rbB,bodyB,pointInB,
+ i,linear_axis, m_AnchorPos);
+
+ }
+ }
+
+ // angular
+ btVector3 angular_axis;
+ btScalar angularJacDiagABInv;
+ for (i=0;i<3;i++)
+ {
+ if (m_angularLimits[i].needApplyTorques())
+ {
+
+ // get axis
+ angular_axis = getAxis(i);
+
+ angularJacDiagABInv = btScalar(1.) / m_jacAng[i].getDiagonal();
+
+ m_angularLimits[i].solveAngularLimits(m_timeStep,angular_axis,angularJacDiagABInv, &m_rbA,bodyA,&m_rbB,bodyB);
+ }
+ }
+ }
}
+//-----------------------------------------------------------------------------
+
void btGeneric6DofConstraint::updateRHS(btScalar timeStep)
{
- (void)timeStep;
+ (void)timeStep;
}
+//-----------------------------------------------------------------------------
+
btVector3 btGeneric6DofConstraint::getAxis(int axis_index) const
{
- return m_calculatedAxis[axis_index];
+ return m_calculatedAxis[axis_index];
}
+//-----------------------------------------------------------------------------
+
btScalar btGeneric6DofConstraint::getAngle(int axis_index) const
{
- return m_calculatedAxisAngleDiff[axis_index];
+ return m_calculatedAxisAngleDiff[axis_index];
}
+//-----------------------------------------------------------------------------
+
void btGeneric6DofConstraint::calcAnchorPos(void)
{
btScalar imA = m_rbA.getInvMass();
@@ -526,3 +686,144 @@ void btGeneric6DofConstraint::calcAnchorPos(void)
return;
} // btGeneric6DofConstraint::calcAnchorPos()
+//-----------------------------------------------------------------------------
+
+void btGeneric6DofConstraint::calculateLinearInfo()
+{
+ m_calculatedLinearDiff = m_calculatedTransformB.getOrigin() - m_calculatedTransformA.getOrigin();
+ m_calculatedLinearDiff = m_calculatedTransformA.getBasis().inverse() * m_calculatedLinearDiff;
+ for(int i = 0; i < 3; i++)
+ {
+ m_linearLimits.testLimitValue(i, m_calculatedLinearDiff[i]);
+ }
+} // btGeneric6DofConstraint::calculateLinearInfo()
+
+//-----------------------------------------------------------------------------
+
+int btGeneric6DofConstraint::get_limit_motor_info2(
+ btRotationalLimitMotor * limot,
+ btRigidBody * body0, btRigidBody * body1,
+ btConstraintInfo2 *info, int row, btVector3& ax1, int rotational)
+{
+ int srow = row * info->rowskip;
+ int powered = limot->m_enableMotor;
+ int limit = limot->m_currentLimit;
+ if (powered || limit)
+ { // if the joint is powered, or has joint limits, add in the extra row
+ btScalar *J1 = rotational ? info->m_J1angularAxis : info->m_J1linearAxis;
+ btScalar *J2 = rotational ? info->m_J2angularAxis : 0;
+ J1[srow+0] = ax1[0];
+ J1[srow+1] = ax1[1];
+ J1[srow+2] = ax1[2];
+ if(rotational)
+ {
+ J2[srow+0] = -ax1[0];
+ J2[srow+1] = -ax1[1];
+ J2[srow+2] = -ax1[2];
+ }
+ if((!rotational) && limit)
+ {
+ btVector3 ltd; // Linear Torque Decoupling vector
+ btVector3 c = m_calculatedTransformB.getOrigin() - body0->getCenterOfMassPosition();
+ ltd = c.cross(ax1);
+ info->m_J1angularAxis[srow+0] = ltd[0];
+ info->m_J1angularAxis[srow+1] = ltd[1];
+ info->m_J1angularAxis[srow+2] = ltd[2];
+
+ c = m_calculatedTransformB.getOrigin() - body1->getCenterOfMassPosition();
+ ltd = -c.cross(ax1);
+ info->m_J2angularAxis[srow+0] = ltd[0];
+ info->m_J2angularAxis[srow+1] = ltd[1];
+ info->m_J2angularAxis[srow+2] = ltd[2];
+ }
+ // if we're limited low and high simultaneously, the joint motor is
+ // ineffective
+ if (limit && (limot->m_loLimit == limot->m_hiLimit)) powered = 0;
+ info->m_constraintError[srow] = btScalar(0.f);
+ if (powered)
+ {
+ info->cfm[srow] = 0.0f;
+ if(!limit)
+ {
+ info->m_constraintError[srow] += limot->m_targetVelocity;
+ info->m_lowerLimit[srow] = -limot->m_maxMotorForce;
+ info->m_upperLimit[srow] = limot->m_maxMotorForce;
+ }
+ }
+ if(limit)
+ {
+ btScalar k = info->fps * limot->m_ERP;
+ if(!rotational)
+ {
+ info->m_constraintError[srow] += k * limot->m_currentLimitError;
+ }
+ else
+ {
+ info->m_constraintError[srow] += -k * limot->m_currentLimitError;
+ }
+ info->cfm[srow] = 0.0f;
+ if (limot->m_loLimit == limot->m_hiLimit)
+ { // limited low and high simultaneously
+ info->m_lowerLimit[srow] = -SIMD_INFINITY;
+ info->m_upperLimit[srow] = SIMD_INFINITY;
+ }
+ else
+ {
+ if (limit == 1)
+ {
+ info->m_lowerLimit[srow] = 0;
+ info->m_upperLimit[srow] = SIMD_INFINITY;
+ }
+ else
+ {
+ info->m_lowerLimit[srow] = -SIMD_INFINITY;
+ info->m_upperLimit[srow] = 0;
+ }
+ // deal with bounce
+ if (limot->m_bounce > 0)
+ {
+ // calculate joint velocity
+ btScalar vel;
+ if (rotational)
+ {
+ vel = body0->getAngularVelocity().dot(ax1);
+ if (body1)
+ vel -= body1->getAngularVelocity().dot(ax1);
+ }
+ else
+ {
+ vel = body0->getLinearVelocity().dot(ax1);
+ if (body1)
+ vel -= body1->getLinearVelocity().dot(ax1);
+ }
+ // only apply bounce if the velocity is incoming, and if the
+ // resulting c[] exceeds what we already have.
+ if (limit == 1)
+ {
+ if (vel < 0)
+ {
+ btScalar newc = -limot->m_bounce* vel;
+ if (newc > info->m_constraintError[srow])
+ info->m_constraintError[srow] = newc;
+ }
+ }
+ else
+ {
+ if (vel > 0)
+ {
+ btScalar newc = -limot->m_bounce * vel;
+ if (newc < info->m_constraintError[srow])
+ info->m_constraintError[srow] = newc;
+ }
+ }
+ }
+ }
+ }
+ return 1;
+ }
+ else return 0;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
index f0718d2d4a0..0ae161d5bdf 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
@@ -30,6 +30,8 @@ http://gimpact.sf.net
class btRigidBody;
+
+
//! Rotation Limit structure for generic joints
class btRotationalLimitMotor
{
@@ -92,7 +94,7 @@ public:
//! Is limited
bool isLimited()
{
- if(m_loLimit>=m_hiLimit) return false;
+ if(m_loLimit > m_hiLimit) return false;
return true;
}
@@ -110,8 +112,7 @@ public:
int testLimitValue(btScalar test_value);
//! apply the correction impulses for two bodies
- btScalar solveAngularLimits(btScalar timeStep,btVector3& axis, btScalar jacDiagABInv,btRigidBody * body0, btRigidBody * body1);
-
+ btScalar solveAngularLimits(btScalar timeStep,btVector3& axis, btScalar jacDiagABInv,btRigidBody * body0, btSolverBody& bodyA,btRigidBody * body1,btSolverBody& bodyB);
};
@@ -129,6 +130,11 @@ public:
btScalar m_damping;//!< Damping for linear limit
btScalar m_restitution;//! Bounce parameter for linear limit
//!@}
+ bool m_enableMotor[3];
+ btVector3 m_targetVelocity;//!< target motor velocity
+ btVector3 m_maxMotorForce;//!< max force on motor
+ btVector3 m_currentLimitError;//! How much is violated this limit
+ int m_currentLimit[3];//!< 0=free, 1=at lower limit, 2=at upper limit
btTranslationalLimitMotor()
{
@@ -139,6 +145,12 @@ public:
m_limitSoftness = 0.7f;
m_damping = btScalar(1.0f);
m_restitution = btScalar(0.5f);
+ for(int i=0; i < 3; i++)
+ {
+ m_enableMotor[i] = false;
+ m_targetVelocity[i] = btScalar(0.f);
+ m_maxMotorForce[i] = btScalar(0.f);
+ }
}
btTranslationalLimitMotor(const btTranslationalLimitMotor & other )
@@ -150,6 +162,12 @@ public:
m_limitSoftness = other.m_limitSoftness ;
m_damping = other.m_damping;
m_restitution = other.m_restitution;
+ for(int i=0; i < 3; i++)
+ {
+ m_enableMotor[i] = other.m_enableMotor[i];
+ m_targetVelocity[i] = other.m_targetVelocity[i];
+ m_maxMotorForce[i] = other.m_maxMotorForce[i];
+ }
}
//! Test limit
@@ -163,13 +181,19 @@ public:
{
return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]);
}
+ inline bool needApplyForce(int limitIndex)
+ {
+ if(m_currentLimit[limitIndex] == 0 && m_enableMotor[limitIndex] == false) return false;
+ return true;
+ }
+ int testLimitValue(int limitIndex, btScalar test_value);
btScalar solveLinearAxis(
btScalar timeStep,
btScalar jacDiagABInv,
- btRigidBody& body1,const btVector3 &pointInA,
- btRigidBody& body2,const btVector3 &pointInB,
+ btRigidBody& body1,btSolverBody& bodyA,const btVector3 &pointInA,
+ btRigidBody& body2,btSolverBody& bodyB,const btVector3 &pointInB,
int limit_index,
const btVector3 & axis_normal_on_a,
const btVector3 & anchorPos);
@@ -247,6 +271,7 @@ protected:
btTransform m_calculatedTransformB;
btVector3 m_calculatedAxisAngleDiff;
btVector3 m_calculatedAxis[3];
+ btVector3 m_calculatedLinearDiff;
btVector3 m_AnchorPos; // point betwen pivots of bodies A and B to solve linear axes
@@ -262,6 +287,9 @@ protected:
}
+ int setAngularLimits(btConstraintInfo2 *info, int row_offset);
+
+ int setLinearLimits(btConstraintInfo2 *info);
void buildLinearJacobian(
btJacobianEntry & jacLinear,const btVector3 & normalWorld,
@@ -269,6 +297,8 @@ protected:
void buildAngularJacobian(btJacobianEntry & jacAngular,const btVector3 & jointAxisW);
+ // tests linear limits
+ void calculateLinearInfo();
//! calcs the euler angles between the two bodies.
void calculateAngleInfo();
@@ -276,6 +306,10 @@ protected:
public:
+
+ ///for backwards compatibility during the transition to 'getInfo/getInfo2'
+ bool m_useSolveConstraintObsolete;
+
btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
btGeneric6DofConstraint();
@@ -330,7 +364,11 @@ public:
//! performs Jacobian calculation, and also calculates angle differences and axis
virtual void buildJacobian();
- virtual void solveConstraint(btScalar timeStep);
+ virtual void getInfo1 (btConstraintInfo1* info);
+
+ virtual void getInfo2 (btConstraintInfo2* info);
+
+ virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep);
void updateRHS(btScalar timeStep);
@@ -432,6 +470,11 @@ public:
virtual void calcAnchorPos(void); // overridable
+ int get_limit_motor_info2( btRotationalLimitMotor * limot,
+ btRigidBody * body0, btRigidBody * body1,
+ btConstraintInfo2 *info, int row, btVector3& ax1, int rotational);
+
+
};
#endif //GENERIC_6DOF_CONSTRAINT_H
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
index a0523a8c76b..b6b34305804 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
@@ -19,19 +19,33 @@ subject to the following restrictions:
#include "LinearMath/btTransformUtil.h"
#include "LinearMath/btMinMax.h"
#include <new>
+#include "btSolverBody.h"
+
+//-----------------------------------------------------------------------------
+
+#define HINGE_USE_OBSOLETE_SOLVER false
+
+//-----------------------------------------------------------------------------
btHingeConstraint::btHingeConstraint()
: btTypedConstraint (HINGE_CONSTRAINT_TYPE),
-m_enableAngularMotor(false)
+m_enableAngularMotor(false),
+m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER),
+m_useReferenceFrameA(false)
{
+ m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f);
}
+//-----------------------------------------------------------------------------
+
btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB,
- btVector3& axisInA,btVector3& axisInB)
+ btVector3& axisInA,btVector3& axisInB, bool useReferenceFrameA)
:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA,rbB),
m_angularOnly(false),
- m_enableAngularMotor(false)
+ m_enableAngularMotor(false),
+ m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER),
+ m_useReferenceFrameA(useReferenceFrameA)
{
m_rbAFrame.getOrigin() = pivotInA;
@@ -60,9 +74,9 @@ btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const bt
btVector3 rbAxisB2 = axisInB.cross(rbAxisB1);
m_rbBFrame.getOrigin() = pivotInB;
- m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),-axisInB.getX(),
- rbAxisB1.getY(),rbAxisB2.getY(),-axisInB.getY(),
- rbAxisB1.getZ(),rbAxisB2.getZ(),-axisInB.getZ() );
+ m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(),
+ rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(),
+ rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() );
//start with free
m_lowerLimit = btScalar(1e30);
@@ -71,32 +85,28 @@ btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const bt
m_relaxationFactor = 1.0f;
m_limitSoftness = 0.9f;
m_solveLimit = false;
-
+ m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f);
}
+//-----------------------------------------------------------------------------
-btHingeConstraint::btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA)
-:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA), m_angularOnly(false), m_enableAngularMotor(false)
+btHingeConstraint::btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA, bool useReferenceFrameA)
+:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA), m_angularOnly(false), m_enableAngularMotor(false),
+m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER),
+m_useReferenceFrameA(useReferenceFrameA)
{
// since no frame is given, assume this to be zero angle and just pick rb transform axis
// fixed axis in worldspace
- btVector3 rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(0);
- btScalar projection = rbAxisA1.dot(axisInA);
- if (projection > SIMD_EPSILON)
- rbAxisA1 = rbAxisA1*projection - axisInA;
- else
- rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(1);
-
- btVector3 rbAxisA2 = axisInA.cross(rbAxisA1);
+ btVector3 rbAxisA1, rbAxisA2;
+ btPlaneSpace1(axisInA, rbAxisA1, rbAxisA2);
m_rbAFrame.getOrigin() = pivotInA;
m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(),
rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(),
rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() );
-
- btVector3 axisInB = rbA.getCenterOfMassTransform().getBasis() * -axisInA;
+ btVector3 axisInB = rbA.getCenterOfMassTransform().getBasis() * axisInA;
btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB);
btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1);
@@ -115,19 +125,19 @@ btHingeConstraint::btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,
m_relaxationFactor = 1.0f;
m_limitSoftness = 0.9f;
m_solveLimit = false;
+ m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f);
}
+//-----------------------------------------------------------------------------
+
btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB,
- const btTransform& rbAFrame, const btTransform& rbBFrame)
+ const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA)
:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame),
m_angularOnly(false),
-m_enableAngularMotor(false)
+m_enableAngularMotor(false),
+m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER),
+m_useReferenceFrameA(useReferenceFrameA)
{
- // flip axis
- m_rbBFrame.getBasis()[0][2] *= btScalar(-1.);
- m_rbBFrame.getBasis()[1][2] *= btScalar(-1.);
- m_rbBFrame.getBasis()[2][2] *= btScalar(-1.);
-
//start with free
m_lowerLimit = btScalar(1e30);
m_upperLimit = btScalar(-1e30);
@@ -135,22 +145,20 @@ m_enableAngularMotor(false)
m_relaxationFactor = 1.0f;
m_limitSoftness = 0.9f;
m_solveLimit = false;
+ m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f);
}
+//-----------------------------------------------------------------------------
-
-btHingeConstraint::btHingeConstraint(btRigidBody& rbA, const btTransform& rbAFrame)
+btHingeConstraint::btHingeConstraint(btRigidBody& rbA, const btTransform& rbAFrame, bool useReferenceFrameA)
:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA),m_rbAFrame(rbAFrame),m_rbBFrame(rbAFrame),
m_angularOnly(false),
-m_enableAngularMotor(false)
+m_enableAngularMotor(false),
+m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER),
+m_useReferenceFrameA(useReferenceFrameA)
{
///not providing rigidbody B means implicitly using worldspace for body B
- // flip axis
- m_rbBFrame.getBasis()[0][2] *= btScalar(-1.);
- m_rbBFrame.getBasis()[1][2] *= btScalar(-1.);
- m_rbBFrame.getBasis()[2][2] *= btScalar(-1.);
-
m_rbBFrame.getOrigin() = m_rbA.getCenterOfMassTransform()(m_rbAFrame.getOrigin());
//start with free
@@ -160,33 +168,38 @@ m_enableAngularMotor(false)
m_relaxationFactor = 1.0f;
m_limitSoftness = 0.9f;
m_solveLimit = false;
+ m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f);
}
+//-----------------------------------------------------------------------------
+
void btHingeConstraint::buildJacobian()
{
- m_appliedImpulse = btScalar(0.);
-
- if (!m_angularOnly)
+ if (m_useSolveConstraintObsolete)
{
- btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin();
- btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin();
- btVector3 relPos = pivotBInW - pivotAInW;
+ m_appliedImpulse = btScalar(0.);
- btVector3 normal[3];
- if (relPos.length2() > SIMD_EPSILON)
+ if (!m_angularOnly)
{
- normal[0] = relPos.normalized();
- }
- else
- {
- normal[0].setValue(btScalar(1.0),0,0);
- }
+ btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin();
+ btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin();
+ btVector3 relPos = pivotBInW - pivotAInW;
+
+ btVector3 normal[3];
+ if (relPos.length2() > SIMD_EPSILON)
+ {
+ normal[0] = relPos.normalized();
+ }
+ else
+ {
+ normal[0].setValue(btScalar(1.0),0,0);
+ }
- btPlaneSpace1(normal[0], normal[1], normal[2]);
+ btPlaneSpace1(normal[0], normal[1], normal[2]);
- for (int i=0;i<3;i++)
- {
- new (&m_jac[i]) btJacobianEntry(
+ for (int i=0;i<3;i++)
+ {
+ new (&m_jac[i]) btJacobianEntry(
m_rbA.getCenterOfMassTransform().getBasis().transpose(),
m_rbB.getCenterOfMassTransform().getBasis().transpose(),
pivotAInW - m_rbA.getCenterOfMassPosition(),
@@ -196,214 +209,458 @@ void btHingeConstraint::buildJacobian()
m_rbA.getInvMass(),
m_rbB.getInvInertiaDiagLocal(),
m_rbB.getInvMass());
+ }
}
- }
- //calculate two perpendicular jointAxis, orthogonal to hingeAxis
- //these two jointAxis require equal angular velocities for both bodies
+ //calculate two perpendicular jointAxis, orthogonal to hingeAxis
+ //these two jointAxis require equal angular velocities for both bodies
- //this is unused for now, it's a todo
- btVector3 jointAxis0local;
- btVector3 jointAxis1local;
-
- btPlaneSpace1(m_rbAFrame.getBasis().getColumn(2),jointAxis0local,jointAxis1local);
-
- getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2);
- btVector3 jointAxis0 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis0local;
- btVector3 jointAxis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis1local;
- btVector3 hingeAxisWorld = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2);
+ //this is unused for now, it's a todo
+ btVector3 jointAxis0local;
+ btVector3 jointAxis1local;
- new (&m_jacAng[0]) btJacobianEntry(jointAxis0,
- m_rbA.getCenterOfMassTransform().getBasis().transpose(),
- m_rbB.getCenterOfMassTransform().getBasis().transpose(),
- m_rbA.getInvInertiaDiagLocal(),
- m_rbB.getInvInertiaDiagLocal());
-
- new (&m_jacAng[1]) btJacobianEntry(jointAxis1,
- m_rbA.getCenterOfMassTransform().getBasis().transpose(),
- m_rbB.getCenterOfMassTransform().getBasis().transpose(),
- m_rbA.getInvInertiaDiagLocal(),
- m_rbB.getInvInertiaDiagLocal());
-
- new (&m_jacAng[2]) btJacobianEntry(hingeAxisWorld,
- m_rbA.getCenterOfMassTransform().getBasis().transpose(),
- m_rbB.getCenterOfMassTransform().getBasis().transpose(),
- m_rbA.getInvInertiaDiagLocal(),
- m_rbB.getInvInertiaDiagLocal());
+ btPlaneSpace1(m_rbAFrame.getBasis().getColumn(2),jointAxis0local,jointAxis1local);
+ getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2);
+ btVector3 jointAxis0 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis0local;
+ btVector3 jointAxis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis1local;
+ btVector3 hingeAxisWorld = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2);
+
+ new (&m_jacAng[0]) btJacobianEntry(jointAxis0,
+ m_rbA.getCenterOfMassTransform().getBasis().transpose(),
+ m_rbB.getCenterOfMassTransform().getBasis().transpose(),
+ m_rbA.getInvInertiaDiagLocal(),
+ m_rbB.getInvInertiaDiagLocal());
+
+ new (&m_jacAng[1]) btJacobianEntry(jointAxis1,
+ m_rbA.getCenterOfMassTransform().getBasis().transpose(),
+ m_rbB.getCenterOfMassTransform().getBasis().transpose(),
+ m_rbA.getInvInertiaDiagLocal(),
+ m_rbB.getInvInertiaDiagLocal());
+
+ new (&m_jacAng[2]) btJacobianEntry(hingeAxisWorld,
+ m_rbA.getCenterOfMassTransform().getBasis().transpose(),
+ m_rbB.getCenterOfMassTransform().getBasis().transpose(),
+ m_rbA.getInvInertiaDiagLocal(),
+ m_rbB.getInvInertiaDiagLocal());
+
+ // clear accumulator
+ m_accLimitImpulse = btScalar(0.);
+
+ // test angular limit
+ testLimit();
+
+ //Compute K = J*W*J' for hinge axis
+ btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2);
+ m_kHinge = 1.0f / (getRigidBodyA().computeAngularImpulseDenominator(axisA) +
+ getRigidBodyB().computeAngularImpulseDenominator(axisA));
- // Compute limit information
- btScalar hingeAngle = getHingeAngle();
+ }
+}
- //set bias, sign, clear accumulator
- m_correction = btScalar(0.);
- m_limitSign = btScalar(0.);
- m_solveLimit = false;
- m_accLimitImpulse = btScalar(0.);
+//-----------------------------------------------------------------------------
-// if (m_lowerLimit < m_upperLimit)
- if (m_lowerLimit <= m_upperLimit)
+void btHingeConstraint::getInfo1(btConstraintInfo1* info)
+{
+ if (m_useSolveConstraintObsolete)
{
-// if (hingeAngle <= m_lowerLimit*m_limitSoftness)
- if (hingeAngle <= m_lowerLimit)
- {
- m_correction = (m_lowerLimit - hingeAngle);
- m_limitSign = 1.0f;
- m_solveLimit = true;
- }
-// else if (hingeAngle >= m_upperLimit*m_limitSoftness)
- else if (hingeAngle >= m_upperLimit)
+ info->m_numConstraintRows = 0;
+ info->nub = 0;
+ }
+ else
+ {
+ info->m_numConstraintRows = 5; // Fixed 3 linear + 2 angular
+ info->nub = 1;
+ //prepare constraint
+ testLimit();
+ if(getSolveLimit() || getEnableAngularMotor())
{
- m_correction = m_upperLimit - hingeAngle;
- m_limitSign = -1.0f;
- m_solveLimit = true;
+ info->m_numConstraintRows++; // limit 3rd anguar as well
+ info->nub--;
}
}
+} // btHingeConstraint::getInfo1 ()
- //Compute K = J*W*J' for hinge axis
- btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2);
- m_kHinge = 1.0f / (getRigidBodyA().computeAngularImpulseDenominator(axisA) +
- getRigidBodyB().computeAngularImpulseDenominator(axisA));
+//-----------------------------------------------------------------------------
+void btHingeConstraint::getInfo2 (btConstraintInfo2* info)
+{
+ btAssert(!m_useSolveConstraintObsolete);
+ int i, s = info->rowskip;
+ // transforms in world space
+ btTransform trA = m_rbA.getCenterOfMassTransform()*m_rbAFrame;
+ btTransform trB = m_rbB.getCenterOfMassTransform()*m_rbBFrame;
+ // pivot point
+ btVector3 pivotAInW = trA.getOrigin();
+ btVector3 pivotBInW = trB.getOrigin();
+ // linear (all fixed)
+ info->m_J1linearAxis[0] = 1;
+ info->m_J1linearAxis[s + 1] = 1;
+ info->m_J1linearAxis[2 * s + 2] = 1;
+ btVector3 a1 = pivotAInW - m_rbA.getCenterOfMassTransform().getOrigin();
+ {
+ btVector3* angular0 = (btVector3*)(info->m_J1angularAxis);
+ btVector3* angular1 = (btVector3*)(info->m_J1angularAxis + s);
+ btVector3* angular2 = (btVector3*)(info->m_J1angularAxis + 2 * s);
+ btVector3 a1neg = -a1;
+ a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2);
+ }
+ btVector3 a2 = pivotBInW - m_rbB.getCenterOfMassTransform().getOrigin();
+ {
+ btVector3* angular0 = (btVector3*)(info->m_J2angularAxis);
+ btVector3* angular1 = (btVector3*)(info->m_J2angularAxis + s);
+ btVector3* angular2 = (btVector3*)(info->m_J2angularAxis + 2 * s);
+ a2.getSkewSymmetricMatrix(angular0,angular1,angular2);
+ }
+ // linear RHS
+ btScalar k = info->fps * info->erp;
+ for(i = 0; i < 3; i++)
+ {
+ info->m_constraintError[i * s] = k * (pivotBInW[i] - pivotAInW[i]);
+ }
+ // make rotations around X and Y equal
+ // the hinge axis should be the only unconstrained
+ // rotational axis, the angular velocity of the two bodies perpendicular to
+ // the hinge axis should be equal. thus the constraint equations are
+ // p*w1 - p*w2 = 0
+ // q*w1 - q*w2 = 0
+ // where p and q are unit vectors normal to the hinge axis, and w1 and w2
+ // are the angular velocity vectors of the two bodies.
+ // get hinge axis (Z)
+ btVector3 ax1 = trA.getBasis().getColumn(2);
+ // get 2 orthos to hinge axis (X, Y)
+ btVector3 p = trA.getBasis().getColumn(0);
+ btVector3 q = trA.getBasis().getColumn(1);
+ // set the two hinge angular rows
+ int s3 = 3 * info->rowskip;
+ int s4 = 4 * info->rowskip;
+
+ info->m_J1angularAxis[s3 + 0] = p[0];
+ info->m_J1angularAxis[s3 + 1] = p[1];
+ info->m_J1angularAxis[s3 + 2] = p[2];
+ info->m_J1angularAxis[s4 + 0] = q[0];
+ info->m_J1angularAxis[s4 + 1] = q[1];
+ info->m_J1angularAxis[s4 + 2] = q[2];
+
+ info->m_J2angularAxis[s3 + 0] = -p[0];
+ info->m_J2angularAxis[s3 + 1] = -p[1];
+ info->m_J2angularAxis[s3 + 2] = -p[2];
+ info->m_J2angularAxis[s4 + 0] = -q[0];
+ info->m_J2angularAxis[s4 + 1] = -q[1];
+ info->m_J2angularAxis[s4 + 2] = -q[2];
+ // compute the right hand side of the constraint equation. set relative
+ // body velocities along p and q to bring the hinge back into alignment.
+ // if ax1,ax2 are the unit length hinge axes as computed from body1 and
+ // body2, we need to rotate both bodies along the axis u = (ax1 x ax2).
+ // if `theta' is the angle between ax1 and ax2, we need an angular velocity
+ // along u to cover angle erp*theta in one step :
+ // |angular_velocity| = angle/time = erp*theta / stepsize
+ // = (erp*fps) * theta
+ // angular_velocity = |angular_velocity| * (ax1 x ax2) / |ax1 x ax2|
+ // = (erp*fps) * theta * (ax1 x ax2) / sin(theta)
+ // ...as ax1 and ax2 are unit length. if theta is smallish,
+ // theta ~= sin(theta), so
+ // angular_velocity = (erp*fps) * (ax1 x ax2)
+ // ax1 x ax2 is in the plane space of ax1, so we project the angular
+ // velocity to p and q to find the right hand side.
+ btVector3 ax2 = trB.getBasis().getColumn(2);
+ btVector3 u = ax1.cross(ax2);
+ info->m_constraintError[s3] = k * u.dot(p);
+ info->m_constraintError[s4] = k * u.dot(q);
+ // check angular limits
+ int nrow = 4; // last filled row
+ int srow;
+ btScalar limit_err = btScalar(0.0);
+ int limit = 0;
+ if(getSolveLimit())
+ {
+ limit_err = m_correction * m_referenceSign;
+ limit = (limit_err > btScalar(0.0)) ? 1 : 2;
+ }
+ // if the hinge has joint limits or motor, add in the extra row
+ int powered = 0;
+ if(getEnableAngularMotor())
+ {
+ powered = 1;
+ }
+ if(limit || powered)
+ {
+ nrow++;
+ srow = nrow * info->rowskip;
+ info->m_J1angularAxis[srow+0] = ax1[0];
+ info->m_J1angularAxis[srow+1] = ax1[1];
+ info->m_J1angularAxis[srow+2] = ax1[2];
+
+ info->m_J2angularAxis[srow+0] = -ax1[0];
+ info->m_J2angularAxis[srow+1] = -ax1[1];
+ info->m_J2angularAxis[srow+2] = -ax1[2];
+
+ btScalar lostop = getLowerLimit();
+ btScalar histop = getUpperLimit();
+ if(limit && (lostop == histop))
+ { // the joint motor is ineffective
+ powered = 0;
+ }
+ info->m_constraintError[srow] = btScalar(0.0f);
+ if(powered)
+ {
+ info->cfm[srow] = btScalar(0.0);
+ btScalar mot_fact = getMotorFactor(m_hingeAngle, lostop, histop, m_motorTargetVelocity, info->fps * info->erp);
+ info->m_constraintError[srow] += mot_fact * m_motorTargetVelocity * m_referenceSign;
+ info->m_lowerLimit[srow] = - m_maxMotorImpulse;
+ info->m_upperLimit[srow] = m_maxMotorImpulse;
+ }
+ if(limit)
+ {
+ k = info->fps * info->erp;
+ info->m_constraintError[srow] += k * limit_err;
+ info->cfm[srow] = btScalar(0.0);
+ if(lostop == histop)
+ {
+ // limited low and high simultaneously
+ info->m_lowerLimit[srow] = -SIMD_INFINITY;
+ info->m_upperLimit[srow] = SIMD_INFINITY;
+ }
+ else if(limit == 1)
+ { // low limit
+ info->m_lowerLimit[srow] = 0;
+ info->m_upperLimit[srow] = SIMD_INFINITY;
+ }
+ else
+ { // high limit
+ info->m_lowerLimit[srow] = -SIMD_INFINITY;
+ info->m_upperLimit[srow] = 0;
+ }
+ // bounce (we'll use slider parameter abs(1.0 - m_dampingLimAng) for that)
+ btScalar bounce = m_relaxationFactor;
+ if(bounce > btScalar(0.0))
+ {
+ btScalar vel = m_rbA.getAngularVelocity().dot(ax1);
+ vel -= m_rbB.getAngularVelocity().dot(ax1);
+ // only apply bounce if the velocity is incoming, and if the
+ // resulting c[] exceeds what we already have.
+ if(limit == 1)
+ { // low limit
+ if(vel < 0)
+ {
+ btScalar newc = -bounce * vel;
+ if(newc > info->m_constraintError[srow])
+ {
+ info->m_constraintError[srow] = newc;
+ }
+ }
+ }
+ else
+ { // high limit - all those computations are reversed
+ if(vel > 0)
+ {
+ btScalar newc = -bounce * vel;
+ if(newc < info->m_constraintError[srow])
+ {
+ info->m_constraintError[srow] = newc;
+ }
+ }
+ }
+ }
+ info->m_constraintError[srow] *= m_biasFactor;
+ } // if(limit)
+ } // if angular limit or powered
}
-void btHingeConstraint::solveConstraint(btScalar timeStep)
+//-----------------------------------------------------------------------------
+
+void btHingeConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep)
{
- btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin();
- btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin();
+ ///for backwards compatibility during the transition to 'getInfo/getInfo2'
+ if (m_useSolveConstraintObsolete)
+ {
+
+ btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin();
+ btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin();
- btScalar tau = btScalar(0.3);
+ btScalar tau = btScalar(0.3);
- //linear part
- if (!m_angularOnly)
- {
- btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition();
- btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
-
- btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1);
- btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2);
- btVector3 vel = vel1 - vel2;
-
- for (int i=0;i<3;i++)
- {
- const btVector3& normal = m_jac[i].m_linearJointAxis;
- btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal();
-
- btScalar rel_vel;
- rel_vel = normal.dot(vel);
- //positional error (zeroth order error)
- btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal
- btScalar impulse = depth*tau/timeStep * jacDiagABInv - rel_vel * jacDiagABInv;
- m_appliedImpulse += impulse;
- btVector3 impulse_vector = normal * impulse;
- m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition());
- m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition());
+ //linear part
+ if (!m_angularOnly)
+ {
+ btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition();
+ btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
+
+ btVector3 vel1,vel2;
+ bodyA.getVelocityInLocalPointObsolete(rel_pos1,vel1);
+ bodyB.getVelocityInLocalPointObsolete(rel_pos2,vel2);
+ btVector3 vel = vel1 - vel2;
+
+ for (int i=0;i<3;i++)
+ {
+ const btVector3& normal = m_jac[i].m_linearJointAxis;
+ btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal();
+
+ btScalar rel_vel;
+ rel_vel = normal.dot(vel);
+ //positional error (zeroth order error)
+ btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal
+ btScalar impulse = depth*tau/timeStep * jacDiagABInv - rel_vel * jacDiagABInv;
+ m_appliedImpulse += impulse;
+ btVector3 impulse_vector = normal * impulse;
+ btVector3 ftorqueAxis1 = rel_pos1.cross(normal);
+ btVector3 ftorqueAxis2 = rel_pos2.cross(normal);
+ bodyA.applyImpulse(normal*m_rbA.getInvMass(), m_rbA.getInvInertiaTensorWorld()*ftorqueAxis1,impulse);
+ bodyB.applyImpulse(normal*m_rbB.getInvMass(), m_rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-impulse);
+ }
}
- }
-
- {
- ///solve angular part
+
+ {
+ ///solve angular part
- // get axes in world space
- btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2);
- btVector3 axisB = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_rbBFrame.getBasis().getColumn(2);
+ // get axes in world space
+ btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2);
+ btVector3 axisB = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_rbBFrame.getBasis().getColumn(2);
- const btVector3& angVelA = getRigidBodyA().getAngularVelocity();
- const btVector3& angVelB = getRigidBodyB().getAngularVelocity();
+ btVector3 angVelA;
+ bodyA.getAngularVelocity(angVelA);
+ btVector3 angVelB;
+ bodyB.getAngularVelocity(angVelB);
- btVector3 angVelAroundHingeAxisA = axisA * axisA.dot(angVelA);
- btVector3 angVelAroundHingeAxisB = axisB * axisB.dot(angVelB);
+ btVector3 angVelAroundHingeAxisA = axisA * axisA.dot(angVelA);
+ btVector3 angVelAroundHingeAxisB = axisB * axisB.dot(angVelB);
- btVector3 angAorthog = angVelA - angVelAroundHingeAxisA;
- btVector3 angBorthog = angVelB - angVelAroundHingeAxisB;
- btVector3 velrelOrthog = angAorthog-angBorthog;
- {
- //solve orthogonal angular velocity correction
- btScalar relaxation = btScalar(1.);
- btScalar len = velrelOrthog.length();
- if (len > btScalar(0.00001))
+ btVector3 angAorthog = angVelA - angVelAroundHingeAxisA;
+ btVector3 angBorthog = angVelB - angVelAroundHingeAxisB;
+ btVector3 velrelOrthog = angAorthog-angBorthog;
{
- btVector3 normal = velrelOrthog.normalized();
- btScalar denom = getRigidBodyA().computeAngularImpulseDenominator(normal) +
- getRigidBodyB().computeAngularImpulseDenominator(normal);
- // scale for mass and relaxation
- //todo: expose this 0.9 factor to developer
- velrelOrthog *= (btScalar(1.)/denom) * m_relaxationFactor;
- }
+
- //solve angular positional correction
- btVector3 angularError = -axisA.cross(axisB) *(btScalar(1.)/timeStep);
- btScalar len2 = angularError.length();
- if (len2>btScalar(0.00001))
- {
- btVector3 normal2 = angularError.normalized();
- btScalar denom2 = getRigidBodyA().computeAngularImpulseDenominator(normal2) +
- getRigidBodyB().computeAngularImpulseDenominator(normal2);
- angularError *= (btScalar(1.)/denom2) * relaxation;
- }
+ //solve orthogonal angular velocity correction
+ btScalar relaxation = btScalar(1.);
+ btScalar len = velrelOrthog.length();
+ if (len > btScalar(0.00001))
+ {
+ btVector3 normal = velrelOrthog.normalized();
+ btScalar denom = getRigidBodyA().computeAngularImpulseDenominator(normal) +
+ getRigidBodyB().computeAngularImpulseDenominator(normal);
+ // scale for mass and relaxation
+ //velrelOrthog *= (btScalar(1.)/denom) * m_relaxationFactor;
- m_rbA.applyTorqueImpulse(-velrelOrthog+angularError);
- m_rbB.applyTorqueImpulse(velrelOrthog-angularError);
+ bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*velrelOrthog,-(btScalar(1.)/denom));
+ bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*velrelOrthog,(btScalar(1.)/denom));
- // solve limit
- if (m_solveLimit)
- {
- btScalar amplitude = ( (angVelB - angVelA).dot( axisA )*m_relaxationFactor + m_correction* (btScalar(1.)/timeStep)*m_biasFactor ) * m_limitSign;
+ }
- btScalar impulseMag = amplitude * m_kHinge;
+ //solve angular positional correction
+ btVector3 angularError = axisA.cross(axisB) *(btScalar(1.)/timeStep);
+ btScalar len2 = angularError.length();
+ if (len2>btScalar(0.00001))
+ {
+ btVector3 normal2 = angularError.normalized();
+ btScalar denom2 = getRigidBodyA().computeAngularImpulseDenominator(normal2) +
+ getRigidBodyB().computeAngularImpulseDenominator(normal2);
+ //angularError *= (btScalar(1.)/denom2) * relaxation;
+
+ bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*angularError,(btScalar(1.)/denom2));
+ bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*angularError,-(btScalar(1.)/denom2));
- // Clamp the accumulated impulse
- btScalar temp = m_accLimitImpulse;
- m_accLimitImpulse = btMax(m_accLimitImpulse + impulseMag, btScalar(0) );
- impulseMag = m_accLimitImpulse - temp;
+ }
+
+
- btVector3 impulse = axisA * impulseMag * m_limitSign;
- m_rbA.applyTorqueImpulse(impulse);
- m_rbB.applyTorqueImpulse(-impulse);
- }
- }
- //apply motor
- if (m_enableAngularMotor)
- {
- //todo: add limits too
- btVector3 angularLimit(0,0,0);
+ // solve limit
+ if (m_solveLimit)
+ {
+ btScalar amplitude = ( (angVelB - angVelA).dot( axisA )*m_relaxationFactor + m_correction* (btScalar(1.)/timeStep)*m_biasFactor ) * m_limitSign;
+
+ btScalar impulseMag = amplitude * m_kHinge;
+
+ // Clamp the accumulated impulse
+ btScalar temp = m_accLimitImpulse;
+ m_accLimitImpulse = btMax(m_accLimitImpulse + impulseMag, btScalar(0) );
+ impulseMag = m_accLimitImpulse - temp;
+
+
+
+ bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*axisA,impulseMag * m_limitSign);
+ bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*axisA,-(impulseMag * m_limitSign));
+
+ }
+ }
- btVector3 velrel = angVelAroundHingeAxisA - angVelAroundHingeAxisB;
- btScalar projRelVel = velrel.dot(axisA);
+ //apply motor
+ if (m_enableAngularMotor)
+ {
+ //todo: add limits too
+ btVector3 angularLimit(0,0,0);
- btScalar desiredMotorVel = m_motorTargetVelocity;
- btScalar motor_relvel = desiredMotorVel - projRelVel;
+ btVector3 velrel = angVelAroundHingeAxisA - angVelAroundHingeAxisB;
+ btScalar projRelVel = velrel.dot(axisA);
- btScalar unclippedMotorImpulse = m_kHinge * motor_relvel;;
- //todo: should clip against accumulated impulse
- btScalar clippedMotorImpulse = unclippedMotorImpulse > m_maxMotorImpulse ? m_maxMotorImpulse : unclippedMotorImpulse;
- clippedMotorImpulse = clippedMotorImpulse < -m_maxMotorImpulse ? -m_maxMotorImpulse : clippedMotorImpulse;
- btVector3 motorImp = clippedMotorImpulse * axisA;
+ btScalar desiredMotorVel = m_motorTargetVelocity;
+ btScalar motor_relvel = desiredMotorVel - projRelVel;
- m_rbA.applyTorqueImpulse(motorImp+angularLimit);
- m_rbB.applyTorqueImpulse(-motorImp-angularLimit);
+ btScalar unclippedMotorImpulse = m_kHinge * motor_relvel;;
+ //todo: should clip against accumulated impulse
+ btScalar clippedMotorImpulse = unclippedMotorImpulse > m_maxMotorImpulse ? m_maxMotorImpulse : unclippedMotorImpulse;
+ clippedMotorImpulse = clippedMotorImpulse < -m_maxMotorImpulse ? -m_maxMotorImpulse : clippedMotorImpulse;
+ btVector3 motorImp = clippedMotorImpulse * axisA;
+ bodyA.applyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*axisA,clippedMotorImpulse);
+ bodyB.applyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*axisA,-clippedMotorImpulse);
+
+ }
}
}
}
+//-----------------------------------------------------------------------------
+
void btHingeConstraint::updateRHS(btScalar timeStep)
{
(void)timeStep;
}
+//-----------------------------------------------------------------------------
+
btScalar btHingeConstraint::getHingeAngle()
{
const btVector3 refAxis0 = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(0);
const btVector3 refAxis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(1);
const btVector3 swingAxis = getRigidBodyB().getCenterOfMassTransform().getBasis() * m_rbBFrame.getBasis().getColumn(1);
-
- return btAtan2Fast( swingAxis.dot(refAxis0), swingAxis.dot(refAxis1) );
+ btScalar angle = btAtan2Fast(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1));
+ return m_referenceSign * angle;
}
+//-----------------------------------------------------------------------------
+
+void btHingeConstraint::testLimit()
+{
+ // Compute limit information
+ m_hingeAngle = getHingeAngle();
+ m_correction = btScalar(0.);
+ m_limitSign = btScalar(0.);
+ m_solveLimit = false;
+ if (m_lowerLimit <= m_upperLimit)
+ {
+ if (m_hingeAngle <= m_lowerLimit)
+ {
+ m_correction = (m_lowerLimit - m_hingeAngle);
+ m_limitSign = 1.0f;
+ m_solveLimit = true;
+ }
+ else if (m_hingeAngle >= m_upperLimit)
+ {
+ m_correction = m_upperLimit - m_hingeAngle;
+ m_limitSign = -1.0f;
+ m_solveLimit = true;
+ }
+ }
+ return;
+} // btHingeConstraint::testLimit()
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h
index 4fa9972f6d8..0af655f4409 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h
@@ -53,27 +53,35 @@ public:
btScalar m_correction;
btScalar m_accLimitImpulse;
+ btScalar m_hingeAngle;
+ btScalar m_referenceSign;
bool m_angularOnly;
bool m_enableAngularMotor;
bool m_solveLimit;
+ bool m_useSolveConstraintObsolete;
+ bool m_useReferenceFrameA;
public:
- btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, btVector3& axisInA,btVector3& axisInB);
+ btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, btVector3& axisInA,btVector3& axisInB, bool useReferenceFrameA = false);
- btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA);
+ btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA, bool useReferenceFrameA = false);
- btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame);
+ btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false);
- btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame);
+ btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA = false);
btHingeConstraint();
virtual void buildJacobian();
- virtual void solveConstraint(btScalar timeStep);
+ virtual void getInfo1 (btConstraintInfo1* info);
+
+ virtual void getInfo2 (btConstraintInfo2* info);
+
+ virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep);
void updateRHS(btScalar timeStep);
@@ -86,6 +94,16 @@ public:
return m_rbB;
}
+ btRigidBody& getRigidBodyA()
+ {
+ return m_rbA;
+ }
+
+ btRigidBody& getRigidBodyB()
+ {
+ return m_rbB;
+ }
+
void setAngularOnly(bool angularOnly)
{
m_angularOnly = angularOnly;
@@ -122,6 +140,8 @@ public:
btScalar getHingeAngle();
+ void testLimit();
+
const btTransform& getAFrame() { return m_rbAFrame; };
const btTransform& getBFrame() { return m_rbBFrame; };
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
index 2b69ad90438..1da749517e8 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
@@ -21,33 +21,38 @@ subject to the following restrictions:
btPoint2PointConstraint::btPoint2PointConstraint()
-:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE)
+:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE),
+m_useSolveConstraintObsolete(false)
{
}
btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB)
-:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA,rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB)
+:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA,rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB),
+m_useSolveConstraintObsolete(false)
{
}
btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA)
-:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA))
+:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA)),
+m_useSolveConstraintObsolete(false)
{
}
void btPoint2PointConstraint::buildJacobian()
{
- m_appliedImpulse = btScalar(0.);
+ ///we need it for both methods
+ {
+ m_appliedImpulse = btScalar(0.);
- btVector3 normal(0,0,0);
+ btVector3 normal(0,0,0);
- for (int i=0;i<3;i++)
- {
- normal[i] = 1;
- new (&m_jac[i]) btJacobianEntry(
+ for (int i=0;i<3;i++)
+ {
+ normal[i] = 1;
+ new (&m_jac[i]) btJacobianEntry(
m_rbA.getCenterOfMassTransform().getBasis().transpose(),
m_rbB.getCenterOfMassTransform().getBasis().transpose(),
m_rbA.getCenterOfMassTransform()*m_pivotInA - m_rbA.getCenterOfMassPosition(),
@@ -58,64 +63,162 @@ void btPoint2PointConstraint::buildJacobian()
m_rbB.getInvInertiaDiagLocal(),
m_rbB.getInvMass());
normal[i] = 0;
+ }
}
}
-void btPoint2PointConstraint::solveConstraint(btScalar timeStep)
-{
- btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_pivotInA;
- btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_pivotInB;
+void btPoint2PointConstraint::getInfo1 (btConstraintInfo1* info)
+{
+ if (m_useSolveConstraintObsolete)
+ {
+ info->m_numConstraintRows = 0;
+ info->nub = 0;
+ } else
+ {
+ info->m_numConstraintRows = 3;
+ info->nub = 3;
+ }
+}
- btVector3 normal(0,0,0);
+void btPoint2PointConstraint::getInfo2 (btConstraintInfo2* info)
+{
+ btAssert(!m_useSolveConstraintObsolete);
+
+ //retrieve matrices
+ btTransform body0_trans;
+ body0_trans = m_rbA.getCenterOfMassTransform();
+ btTransform body1_trans;
+ body1_trans = m_rbB.getCenterOfMassTransform();
+
+ // anchor points in global coordinates with respect to body PORs.
+
+ // set jacobian
+ info->m_J1linearAxis[0] = 1;
+ info->m_J1linearAxis[info->rowskip+1] = 1;
+ info->m_J1linearAxis[2*info->rowskip+2] = 1;
+
+ btVector3 a1 = body0_trans.getBasis()*getPivotInA();
+ {
+ btVector3* angular0 = (btVector3*)(info->m_J1angularAxis);
+ btVector3* angular1 = (btVector3*)(info->m_J1angularAxis+info->rowskip);
+ btVector3* angular2 = (btVector3*)(info->m_J1angularAxis+2*info->rowskip);
+ btVector3 a1neg = -a1;
+ a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2);
+ }
+
+ /*info->m_J2linearAxis[0] = -1;
+ info->m_J2linearAxis[s+1] = -1;
+ info->m_J2linearAxis[2*s+2] = -1;
+ */
+ btVector3 a2 = body1_trans.getBasis()*getPivotInB();
+
+ {
+ btVector3 a2n = -a2;
+ btVector3* angular0 = (btVector3*)(info->m_J2angularAxis);
+ btVector3* angular1 = (btVector3*)(info->m_J2angularAxis+info->rowskip);
+ btVector3* angular2 = (btVector3*)(info->m_J2angularAxis+2*info->rowskip);
+ a2.getSkewSymmetricMatrix(angular0,angular1,angular2);
+ }
+
-// btVector3 angvelA = m_rbA.getCenterOfMassTransform().getBasis().transpose() * m_rbA.getAngularVelocity();
-// btVector3 angvelB = m_rbB.getCenterOfMassTransform().getBasis().transpose() * m_rbB.getAngularVelocity();
-
- for (int i=0;i<3;i++)
- {
- normal[i] = 1;
- btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal();
- btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition();
- btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
- //this jacobian entry could be re-used for all iterations
-
- btVector3 vel1 = m_rbA.getVelocityInLocalPoint(rel_pos1);
- btVector3 vel2 = m_rbB.getVelocityInLocalPoint(rel_pos2);
- btVector3 vel = vel1 - vel2;
-
- btScalar rel_vel;
- rel_vel = normal.dot(vel);
+ // set right hand side
+ btScalar k = info->fps * info->erp;
+ int j;
- /*
- //velocity error (first order error)
- btScalar rel_vel = m_jac[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA,
- m_rbB.getLinearVelocity(),angvelB);
- */
-
- //positional error (zeroth order error)
- btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal
-
- btScalar impulse = depth*m_setting.m_tau/timeStep * jacDiagABInv - m_setting.m_damping * rel_vel * jacDiagABInv;
+ for (j=0; j<3; j++)
+ {
+ info->m_constraintError[j*info->rowskip] = k * (a2[j] + body1_trans.getOrigin()[j] - a1[j] - body0_trans.getOrigin()[j]);
+ //printf("info->m_constraintError[%d]=%f\n",j,info->m_constraintError[j]);
+ }
- btScalar impulseClamp = m_setting.m_impulseClamp;
- if (impulseClamp > 0)
+ btScalar impulseClamp = m_setting.m_impulseClamp;//
+ for (j=0; j<3; j++)
+ {
+ if (m_setting.m_impulseClamp > 0)
{
- if (impulse < -impulseClamp)
- impulse = -impulseClamp;
- if (impulse > impulseClamp)
- impulse = impulseClamp;
+ info->m_lowerLimit[j*info->rowskip] = -impulseClamp;
+ info->m_upperLimit[j*info->rowskip] = impulseClamp;
}
+ }
+
+}
+
- m_appliedImpulse+=impulse;
- btVector3 impulse_vector = normal * impulse;
- m_rbA.applyImpulse(impulse_vector, pivotAInW - m_rbA.getCenterOfMassPosition());
- m_rbB.applyImpulse(-impulse_vector, pivotBInW - m_rbB.getCenterOfMassPosition());
+void btPoint2PointConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep)
+{
+ if (m_useSolveConstraintObsolete)
+ {
+ btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_pivotInA;
+ btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_pivotInB;
+
+
+ btVector3 normal(0,0,0);
- normal[i] = 0;
+
+ // btVector3 angvelA = m_rbA.getCenterOfMassTransform().getBasis().transpose() * m_rbA.getAngularVelocity();
+ // btVector3 angvelB = m_rbB.getCenterOfMassTransform().getBasis().transpose() * m_rbB.getAngularVelocity();
+
+ for (int i=0;i<3;i++)
+ {
+ normal[i] = 1;
+ btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal();
+
+ btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition();
+ btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
+ //this jacobian entry could be re-used for all iterations
+
+ btVector3 vel1,vel2;
+ bodyA.getVelocityInLocalPointObsolete(rel_pos1,vel1);
+ bodyB.getVelocityInLocalPointObsolete(rel_pos2,vel2);
+ btVector3 vel = vel1 - vel2;
+
+ btScalar rel_vel;
+ rel_vel = normal.dot(vel);
+
+ /*
+ //velocity error (first order error)
+ btScalar rel_vel = m_jac[i].getRelativeVelocity(m_rbA.getLinearVelocity(),angvelA,
+ m_rbB.getLinearVelocity(),angvelB);
+ */
+
+ //positional error (zeroth order error)
+ btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal
+
+ btScalar deltaImpulse = depth*m_setting.m_tau/timeStep * jacDiagABInv - m_setting.m_damping * rel_vel * jacDiagABInv;
+
+ btScalar impulseClamp = m_setting.m_impulseClamp;
+
+ const btScalar sum = btScalar(m_appliedImpulse) + deltaImpulse;
+ if (sum < -impulseClamp)
+ {
+ deltaImpulse = -impulseClamp-m_appliedImpulse;
+ m_appliedImpulse = -impulseClamp;
+ }
+ else if (sum > impulseClamp)
+ {
+ deltaImpulse = impulseClamp-m_appliedImpulse;
+ m_appliedImpulse = impulseClamp;
+ }
+ else
+ {
+ m_appliedImpulse = sum;
+ }
+
+
+ btVector3 impulse_vector = normal * deltaImpulse;
+
+ btVector3 ftorqueAxis1 = rel_pos1.cross(normal);
+ btVector3 ftorqueAxis2 = rel_pos2.cross(normal);
+ bodyA.applyImpulse(normal*m_rbA.getInvMass(), m_rbA.getInvInertiaTensorWorld()*ftorqueAxis1,deltaImpulse);
+ bodyB.applyImpulse(normal*m_rbB.getInvMass(), m_rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-deltaImpulse);
+
+
+ normal[i] = 0;
+ }
}
}
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
index c9d5968530c..e2b865cd484 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
@@ -50,6 +50,9 @@ public:
public:
+ ///for backwards compatibility during the transition to 'getInfo/getInfo2'
+ bool m_useSolveConstraintObsolete;
+
btConstraintSetting m_setting;
btPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB);
@@ -60,8 +63,12 @@ public:
virtual void buildJacobian();
+ virtual void getInfo1 (btConstraintInfo1* info);
+
+ virtual void getInfo2 (btConstraintInfo2* info);
+
- virtual void solveConstraint(btScalar timeStep);
+ virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep);
void updateRHS(btScalar timeStep);
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
index 41e336c9d17..685a812d427 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
@@ -15,7 +15,6 @@ subject to the following restrictions:
//#define COMPUTE_IMPULSE_DENOM 1
//It is not necessary (redundant) to refresh contact manifolds, this refresh has been moved to the collision algorithms.
-//#define FORCE_REFESH_CONTACT_MANIFOLDS 1
#include "btSequentialImpulseConstraintSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
@@ -32,441 +31,264 @@ subject to the following restrictions:
#include "LinearMath/btQuickprof.h"
#include "btSolverBody.h"
#include "btSolverConstraint.h"
-
-
#include "LinearMath/btAlignedObjectArray.h"
+#include <string.h> //for memset
-
-int totalCpd = 0;
-
-int gTotalContactPoints = 0;
-
-struct btOrderIndex
+btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver()
+:m_btSeed2(0)
{
- int m_manifoldIndex;
- int m_pointIndex;
-};
-
-
-
-#define SEQUENTIAL_IMPULSE_MAX_SOLVER_POINTS 16384
-static btOrderIndex gOrder[SEQUENTIAL_IMPULSE_MAX_SOLVER_POINTS];
+}
-unsigned long btSequentialImpulseConstraintSolver::btRand2()
+btSequentialImpulseConstraintSolver::~btSequentialImpulseConstraintSolver()
{
- m_btSeed2 = (1664525L*m_btSeed2 + 1013904223L) & 0xffffffff;
- return m_btSeed2;
}
-
-
-//See ODE: adam's all-int straightforward(?) dRandInt (0..n-1)
-int btSequentialImpulseConstraintSolver::btRandInt2 (int n)
+#ifdef USE_SIMD
+#include <emmintrin.h>
+#define vec_splat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e,e,e,e))
+static inline __m128 _vmathVfDot3( __m128 vec0, __m128 vec1 )
{
- // seems good; xor-fold and modulus
- const unsigned long un = static_cast<unsigned long>(n);
- unsigned long r = btRand2();
-
- // note: probably more aggressive than it needs to be -- might be
- // able to get away without one or two of the innermost branches.
- if (un <= 0x00010000UL) {
- r ^= (r >> 16);
- if (un <= 0x00000100UL) {
- r ^= (r >> 8);
- if (un <= 0x00000010UL) {
- r ^= (r >> 4);
- if (un <= 0x00000004UL) {
- r ^= (r >> 2);
- if (un <= 0x00000002UL) {
- r ^= (r >> 1);
- }
- }
- }
- }
- }
-
- return (int) (r % un);
+ __m128 result = _mm_mul_ps( vec0, vec1);
+ return _mm_add_ps( vec_splat( result, 0 ), _mm_add_ps( vec_splat( result, 1 ), vec_splat( result, 2 ) ) );
}
+#endif//USE_SIMD
-
-
-
-bool MyContactDestroyedCallback(void* userPersistentData);
-bool MyContactDestroyedCallback(void* userPersistentData)
+// Project Gauss Seidel or the equivalent Sequential Impulse
+void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
{
- assert (userPersistentData);
- btConstraintPersistentData* cpd = (btConstraintPersistentData*)userPersistentData;
- btAlignedFree(cpd);
- totalCpd--;
- //printf("totalCpd = %i. DELETED Ptr %x\n",totalCpd,userPersistentData);
- return true;
+#ifdef USE_SIMD
+ __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse);
+ __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit);
+ __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit);
+ __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse),_mm_set1_ps(c.m_cfm)));
+ __m128 deltaVel1Dotn = _mm_add_ps(_vmathVfDot3(c.m_contactNormal.mVec128,body1.m_deltaLinearVelocity.mVec128), _vmathVfDot3(c.m_relpos1CrossNormal.mVec128,body1.m_deltaAngularVelocity.mVec128));
+ __m128 deltaVel2Dotn = _mm_sub_ps(_vmathVfDot3(c.m_relpos2CrossNormal.mVec128,body2.m_deltaAngularVelocity.mVec128),_vmathVfDot3((c.m_contactNormal).mVec128,body2.m_deltaLinearVelocity.mVec128));
+ deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
+ deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
+ btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse);
+ btSimdScalar resultLowerLess,resultUpperLess;
+ resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1);
+ resultUpperLess = _mm_cmplt_ps(sum,upperLimit1);
+ __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp);
+ deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) );
+ c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
+ __m128 upperMinApplied = _mm_sub_ps(upperLimit1,cpAppliedImp);
+ deltaImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, deltaImpulse), _mm_andnot_ps(resultUpperLess, upperMinApplied) );
+ c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, c.m_appliedImpulse), _mm_andnot_ps(resultUpperLess, upperLimit1) );
+ __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.m_invMass.mVec128);
+ __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.m_invMass.mVec128);
+ __m128 impulseMagnitude = deltaImpulse;
+ body1.m_deltaLinearVelocity.mVec128 = _mm_add_ps(body1.m_deltaLinearVelocity.mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
+ body1.m_deltaAngularVelocity.mVec128 = _mm_add_ps(body1.m_deltaAngularVelocity.mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude));
+ body2.m_deltaLinearVelocity.mVec128 = _mm_sub_ps(body2.m_deltaLinearVelocity.mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
+ body2.m_deltaAngularVelocity.mVec128 = _mm_add_ps(body2.m_deltaAngularVelocity.mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude));
+#else
+ resolveSingleConstraintRowGeneric(body1,body2,c);
+#endif
}
-
-
-btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver()
-:m_btSeed2(0)
+// Project Gauss Seidel or the equivalent Sequential Impulse
+ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGeneric(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
{
- gContactDestroyedCallback = &MyContactDestroyedCallback;
+ btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm;
+ const btScalar deltaVel1Dotn = c.m_contactNormal.dot(body1.m_deltaLinearVelocity) + c.m_relpos1CrossNormal.dot(body1.m_deltaAngularVelocity);
+ const btScalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.m_deltaLinearVelocity) + c.m_relpos2CrossNormal.dot(body2.m_deltaAngularVelocity);
- //initialize default friction/contact funcs
- int i,j;
- for (i=0;i<MAX_CONTACT_SOLVER_TYPES;i++)
- for (j=0;j<MAX_CONTACT_SOLVER_TYPES;j++)
- {
+ const btScalar delta_rel_vel = deltaVel1Dotn-deltaVel2Dotn;
+ deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv;
+ deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv;
- m_contactDispatch[i][j] = resolveSingleCollision;
- m_frictionDispatch[i][j] = resolveSingleFriction;
- }
+ const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse;
+ if (sum < c.m_lowerLimit)
+ {
+ deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse;
+ c.m_appliedImpulse = c.m_lowerLimit;
+ }
+ else if (sum > c.m_upperLimit)
+ {
+ deltaImpulse = c.m_upperLimit-c.m_appliedImpulse;
+ c.m_appliedImpulse = c.m_upperLimit;
+ }
+ else
+ {
+ c.m_appliedImpulse = sum;
+ }
+ body1.applyImpulse(c.m_contactNormal*body1.m_invMass,c.m_angularComponentA,deltaImpulse);
+ body2.applyImpulse(-c.m_contactNormal*body2.m_invMass,c.m_angularComponentB,deltaImpulse);
}
-btSequentialImpulseConstraintSolver::~btSequentialImpulseConstraintSolver()
+ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
{
-
+#ifdef USE_SIMD
+ __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse);
+ __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit);
+ __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit);
+ __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse),_mm_set1_ps(c.m_cfm)));
+ __m128 deltaVel1Dotn = _mm_add_ps(_vmathVfDot3(c.m_contactNormal.mVec128,body1.m_deltaLinearVelocity.mVec128), _vmathVfDot3(c.m_relpos1CrossNormal.mVec128,body1.m_deltaAngularVelocity.mVec128));
+ __m128 deltaVel2Dotn = _mm_sub_ps(_vmathVfDot3(c.m_relpos2CrossNormal.mVec128,body2.m_deltaAngularVelocity.mVec128),_vmathVfDot3((c.m_contactNormal).mVec128,body2.m_deltaLinearVelocity.mVec128));
+ deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
+ deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
+ btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse);
+ btSimdScalar resultLowerLess,resultUpperLess;
+ resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1);
+ resultUpperLess = _mm_cmplt_ps(sum,upperLimit1);
+ __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp);
+ deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) );
+ c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
+ __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.m_invMass.mVec128);
+ __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.m_invMass.mVec128);
+ __m128 impulseMagnitude = deltaImpulse;
+ body1.m_deltaLinearVelocity.mVec128 = _mm_add_ps(body1.m_deltaLinearVelocity.mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
+ body1.m_deltaAngularVelocity.mVec128 = _mm_add_ps(body1.m_deltaAngularVelocity.mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude));
+ body2.m_deltaLinearVelocity.mVec128 = _mm_sub_ps(body2.m_deltaLinearVelocity.mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
+ body2.m_deltaAngularVelocity.mVec128 = _mm_add_ps(body2.m_deltaAngularVelocity.mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude));
+#else
+ resolveSingleConstraintRowLowerLimit(body1,body2,c);
+#endif
}
-void initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject);
-void initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject)
+// Project Gauss Seidel or the equivalent Sequential Impulse
+ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimit(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
{
- btRigidBody* rb = btRigidBody::upcast(collisionObject);
- if (rb)
+ btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm;
+ const btScalar deltaVel1Dotn = c.m_contactNormal.dot(body1.m_deltaLinearVelocity) + c.m_relpos1CrossNormal.dot(body1.m_deltaAngularVelocity);
+ const btScalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.m_deltaLinearVelocity) + c.m_relpos2CrossNormal.dot(body2.m_deltaAngularVelocity);
+
+ deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv;
+ deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv;
+ const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse;
+ if (sum < c.m_lowerLimit)
{
- solverBody->m_angularVelocity = rb->getAngularVelocity() ;
- solverBody->m_centerOfMassPosition = collisionObject->getWorldTransform().getOrigin();
- solverBody->m_friction = collisionObject->getFriction();
- solverBody->m_invMass = rb->getInvMass();
- solverBody->m_linearVelocity = rb->getLinearVelocity();
- solverBody->m_originalBody = rb;
- solverBody->m_angularFactor = rb->getAngularFactor();
- } else
+ deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse;
+ c.m_appliedImpulse = c.m_lowerLimit;
+ }
+ else
{
- solverBody->m_angularVelocity.setValue(0,0,0);
- solverBody->m_centerOfMassPosition = collisionObject->getWorldTransform().getOrigin();
- solverBody->m_friction = collisionObject->getFriction();
- solverBody->m_invMass = 0.f;
- solverBody->m_linearVelocity.setValue(0,0,0);
- solverBody->m_originalBody = 0;
- solverBody->m_angularFactor = 1.f;
+ c.m_appliedImpulse = sum;
}
-
- solverBody->m_pushVelocity.setValue(0.f,0.f,0.f);
- solverBody->m_turnVelocity.setValue(0.f,0.f,0.f);
+ body1.applyImpulse(c.m_contactNormal*body1.m_invMass,c.m_angularComponentA,deltaImpulse);
+ body2.applyImpulse(-c.m_contactNormal*body2.m_invMass,c.m_angularComponentB,deltaImpulse);
}
-int gNumSplitImpulseRecoveries = 0;
-btScalar restitutionCurve(btScalar rel_vel, btScalar restitution);
-btScalar restitutionCurve(btScalar rel_vel, btScalar restitution)
+unsigned long btSequentialImpulseConstraintSolver::btRand2()
{
- btScalar rest = restitution * -rel_vel;
- return rest;
+ m_btSeed2 = (1664525L*m_btSeed2 + 1013904223L) & 0xffffffff;
+ return m_btSeed2;
}
-void resolveSplitPenetrationImpulseCacheFriendly(
- btSolverBody& body1,
- btSolverBody& body2,
- const btSolverConstraint& contactConstraint,
- const btContactSolverInfo& solverInfo);
-//SIMD_FORCE_INLINE
-void resolveSplitPenetrationImpulseCacheFriendly(
- btSolverBody& body1,
- btSolverBody& body2,
- const btSolverConstraint& contactConstraint,
- const btContactSolverInfo& solverInfo)
+//See ODE: adam's all-int straightforward(?) dRandInt (0..n-1)
+int btSequentialImpulseConstraintSolver::btRandInt2 (int n)
{
- (void)solverInfo;
-
- if (contactConstraint.m_penetration < solverInfo.m_splitImpulsePenetrationThreshold)
- {
-
- gNumSplitImpulseRecoveries++;
- btScalar normalImpulse;
-
- // Optimized version of projected relative velocity, use precomputed cross products with normal
- // body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1);
- // body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2);
- // btVector3 vel = vel1 - vel2;
- // btScalar rel_vel = contactConstraint.m_contactNormal.dot(vel);
-
- btScalar rel_vel;
- btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_pushVelocity)
- + contactConstraint.m_relpos1CrossNormal.dot(body1.m_turnVelocity);
- btScalar vel2Dotn = contactConstraint.m_contactNormal.dot(body2.m_pushVelocity)
- + contactConstraint.m_relpos2CrossNormal.dot(body2.m_turnVelocity);
-
- rel_vel = vel1Dotn-vel2Dotn;
-
-
- btScalar positionalError = -contactConstraint.m_penetration * solverInfo.m_erp2/solverInfo.m_timeStep;
- // btScalar positionalError = contactConstraint.m_penetration;
-
- btScalar velocityError = contactConstraint.m_restitution - rel_vel;// * damping;
-
- btScalar penetrationImpulse = positionalError * contactConstraint.m_jacDiagABInv;
- btScalar velocityImpulse = velocityError * contactConstraint.m_jacDiagABInv;
- normalImpulse = penetrationImpulse+velocityImpulse;
-
- // See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse
- btScalar oldNormalImpulse = contactConstraint.m_appliedPushImpulse;
- btScalar sum = oldNormalImpulse + normalImpulse;
- contactConstraint.m_appliedPushImpulse = btScalar(0.) > sum ? btScalar(0.): sum;
-
- normalImpulse = contactConstraint.m_appliedPushImpulse - oldNormalImpulse;
-
- body1.internalApplyPushImpulse(contactConstraint.m_contactNormal*body1.m_invMass, contactConstraint.m_angularComponentA,normalImpulse);
-
- body2.internalApplyPushImpulse(contactConstraint.m_contactNormal*body2.m_invMass, contactConstraint.m_angularComponentB,-normalImpulse);
-
- }
+ // seems good; xor-fold and modulus
+ const unsigned long un = static_cast<unsigned long>(n);
+ unsigned long r = btRand2();
+
+ // note: probably more aggressive than it needs to be -- might be
+ // able to get away without one or two of the innermost branches.
+ if (un <= 0x00010000UL) {
+ r ^= (r >> 16);
+ if (un <= 0x00000100UL) {
+ r ^= (r >> 8);
+ if (un <= 0x00000010UL) {
+ r ^= (r >> 4);
+ if (un <= 0x00000004UL) {
+ r ^= (r >> 2);
+ if (un <= 0x00000002UL) {
+ r ^= (r >> 1);
+ }
+ }
+ }
+ }
+ }
+ return (int) (r % un);
}
-//velocity + friction
-//response between two dynamic objects with friction
-
-btScalar resolveSingleCollisionCombinedCacheFriendly(
- btSolverBody& body1,
- btSolverBody& body2,
- const btSolverConstraint& contactConstraint,
- const btContactSolverInfo& solverInfo);
-//SIMD_FORCE_INLINE
-btScalar resolveSingleCollisionCombinedCacheFriendly(
- btSolverBody& body1,
- btSolverBody& body2,
- const btSolverConstraint& contactConstraint,
- const btContactSolverInfo& solverInfo)
+void btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject)
{
- (void)solverInfo;
+ btRigidBody* rb = collisionObject? btRigidBody::upcast(collisionObject) : 0;
- btScalar normalImpulse;
+ solverBody->m_deltaLinearVelocity.setValue(0.f,0.f,0.f);
+ solverBody->m_deltaAngularVelocity.setValue(0.f,0.f,0.f);
+ if (rb)
{
-
-
- // Optimized version of projected relative velocity, use precomputed cross products with normal
- // body1.getVelocityInLocalPoint(contactConstraint.m_rel_posA,vel1);
- // body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2);
- // btVector3 vel = vel1 - vel2;
- // btScalar rel_vel = contactConstraint.m_contactNormal.dot(vel);
-
- btScalar rel_vel;
- btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_linearVelocity)
- + contactConstraint.m_relpos1CrossNormal.dot(body1.m_angularVelocity);
- btScalar vel2Dotn = contactConstraint.m_contactNormal.dot(body2.m_linearVelocity)
- + contactConstraint.m_relpos2CrossNormal.dot(body2.m_angularVelocity);
-
- rel_vel = vel1Dotn-vel2Dotn;
-
- btScalar positionalError = 0.f;
- if (!solverInfo.m_splitImpulse || (contactConstraint.m_penetration > solverInfo.m_splitImpulsePenetrationThreshold))
- {
- positionalError = -contactConstraint.m_penetration * solverInfo.m_erp/solverInfo.m_timeStep;
- }
-
- btScalar velocityError = contactConstraint.m_restitution - rel_vel;// * damping;
-
- btScalar penetrationImpulse = positionalError * contactConstraint.m_jacDiagABInv;
- btScalar velocityImpulse = velocityError * contactConstraint.m_jacDiagABInv;
- normalImpulse = penetrationImpulse+velocityImpulse;
-
-
- // See Erin Catto's GDC 2006 paper: Clamp the accumulated impulse
- btScalar oldNormalImpulse = contactConstraint.m_appliedImpulse;
- btScalar sum = oldNormalImpulse + normalImpulse;
- contactConstraint.m_appliedImpulse = btScalar(0.) > sum ? btScalar(0.): sum;
-
- normalImpulse = contactConstraint.m_appliedImpulse - oldNormalImpulse;
-
- body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass,
- contactConstraint.m_angularComponentA,normalImpulse);
-
- body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass,
- contactConstraint.m_angularComponentB,-normalImpulse);
+ solverBody->m_invMass = btVector3(rb->getInvMass(),rb->getInvMass(),rb->getInvMass())*rb->getLinearFactor();
+ solverBody->m_originalBody = rb;
+ solverBody->m_angularFactor = rb->getAngularFactor();
+ } else
+ {
+ solverBody->m_invMass.setValue(0,0,0);
+ solverBody->m_originalBody = 0;
+ solverBody->m_angularFactor.setValue(1,1,1);
}
-
- return normalImpulse;
}
-//#define NO_FRICTION_TANGENTIALS 1
-#ifndef NO_FRICTION_TANGENTIALS
-
-btScalar resolveSingleFrictionCacheFriendly(
- btSolverBody& body1,
- btSolverBody& body2,
- const btSolverConstraint& contactConstraint,
- const btContactSolverInfo& solverInfo,
- btScalar appliedNormalImpulse);
-
-//SIMD_FORCE_INLINE
-btScalar resolveSingleFrictionCacheFriendly(
- btSolverBody& body1,
- btSolverBody& body2,
- const btSolverConstraint& contactConstraint,
- const btContactSolverInfo& solverInfo,
- btScalar appliedNormalImpulse)
-{
- (void)solverInfo;
-
-
- const btScalar combinedFriction = contactConstraint.m_friction;
-
- const btScalar limit = appliedNormalImpulse * combinedFriction;
-
- if (appliedNormalImpulse>btScalar(0.))
- //friction
- {
-
- btScalar j1;
- {
- btScalar rel_vel;
- const btScalar vel1Dotn = contactConstraint.m_contactNormal.dot(body1.m_linearVelocity)
- + contactConstraint.m_relpos1CrossNormal.dot(body1.m_angularVelocity);
- const btScalar vel2Dotn = contactConstraint.m_contactNormal.dot(body2.m_linearVelocity)
- + contactConstraint.m_relpos2CrossNormal.dot(body2.m_angularVelocity);
- rel_vel = vel1Dotn-vel2Dotn;
-
- // calculate j that moves us to zero relative velocity
- j1 = -rel_vel * contactConstraint.m_jacDiagABInv;
-#define CLAMP_ACCUMULATED_FRICTION_IMPULSE 1
-#ifdef CLAMP_ACCUMULATED_FRICTION_IMPULSE
- btScalar oldTangentImpulse = contactConstraint.m_appliedImpulse;
- contactConstraint.m_appliedImpulse = oldTangentImpulse + j1;
-
- if (limit < contactConstraint.m_appliedImpulse)
- {
- contactConstraint.m_appliedImpulse = limit;
- } else
- {
- if (contactConstraint.m_appliedImpulse < -limit)
- contactConstraint.m_appliedImpulse = -limit;
- }
- j1 = contactConstraint.m_appliedImpulse - oldTangentImpulse;
-#else
- if (limit < j1)
- {
- j1 = limit;
- } else
- {
- if (j1 < -limit)
- j1 = -limit;
- }
-
-#endif //CLAMP_ACCUMULATED_FRICTION_IMPULSE
-
- //GEN_set_min(contactConstraint.m_appliedImpulse, limit);
- //GEN_set_max(contactConstraint.m_appliedImpulse, -limit);
-
-
-
- }
-
- body1.internalApplyImpulse(contactConstraint.m_contactNormal*body1.m_invMass,contactConstraint.m_angularComponentA,j1);
-
- body2.internalApplyImpulse(contactConstraint.m_contactNormal*body2.m_invMass,contactConstraint.m_angularComponentB,-j1);
+int gNumSplitImpulseRecoveries = 0;
- }
- return 0.f;
+btScalar btSequentialImpulseConstraintSolver::restitutionCurve(btScalar rel_vel, btScalar restitution)
+{
+ btScalar rest = restitution * -rel_vel;
+ return rest;
}
-#else
-//velocity + friction
-//response between two dynamic objects with friction
-btScalar resolveSingleFrictionCacheFriendly(
- btSolverBody& body1,
- btSolverBody& body2,
- btSolverConstraint& contactConstraint,
- const btContactSolverInfo& solverInfo)
+void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection);
+void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection)
{
-
- btVector3 vel1;
- btVector3 vel2;
- btScalar normalImpulse(0.f);
-
+ if (colObj && colObj->hasAnisotropicFriction())
{
- const btVector3& normal = contactConstraint.m_contactNormal;
- if (contactConstraint.m_penetration < 0.f)
- return 0.f;
-
-
- body1.getVelocityInLocalPoint(contactConstraint.m_relpos1CrossNormal,vel1);
- body2.getVelocityInLocalPoint(contactConstraint.m_rel_posB,vel2);
- btVector3 vel = vel1 - vel2;
- btScalar rel_vel;
- rel_vel = normal.dot(vel);
-
- btVector3 lat_vel = vel - normal * rel_vel;
- btScalar lat_rel_vel = lat_vel.length2();
-
- btScalar combinedFriction = contactConstraint.m_friction;
- const btVector3& rel_pos1 = contactConstraint.m_rel_posA;
- const btVector3& rel_pos2 = contactConstraint.m_rel_posB;
-
-
- if (lat_rel_vel > SIMD_EPSILON*SIMD_EPSILON)
- {
- lat_rel_vel = btSqrt(lat_rel_vel);
-
- lat_vel /= lat_rel_vel;
- btVector3 temp1 = body1.m_invInertiaWorld * rel_pos1.cross(lat_vel);
- btVector3 temp2 = body2.m_invInertiaWorld * rel_pos2.cross(lat_vel);
- btScalar friction_impulse = lat_rel_vel /
- (body1.m_invMass + body2.m_invMass + lat_vel.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2)));
- btScalar normal_impulse = contactConstraint.m_appliedImpulse * combinedFriction;
-
- btSetMin(friction_impulse, normal_impulse);
- btSetMin(friction_impulse, -normal_impulse);
- body1.internalApplyImpulse(lat_vel * -friction_impulse, rel_pos1);
- body2.applyImpulse(lat_vel * friction_impulse, rel_pos2);
- }
+ // transform to local coordinates
+ btVector3 loc_lateral = frictionDirection * colObj->getWorldTransform().getBasis();
+ const btVector3& friction_scaling = colObj->getAnisotropicFriction();
+ //apply anisotropic friction
+ loc_lateral *= friction_scaling;
+ // ... and transform it back to global coordinates
+ frictionDirection = colObj->getWorldTransform().getBasis() * loc_lateral;
}
-
- return normalImpulse;
}
-#endif //NO_FRICTION_TANGENTIALS
-
-
-
-void btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation)
+btSolverConstraint& btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation)
{
+
btRigidBody* body0=btRigidBody::upcast(colObj0);
btRigidBody* body1=btRigidBody::upcast(colObj1);
- btSolverConstraint& solverConstraint = m_tmpSolverFrictionConstraintPool.expand();
+ btSolverConstraint& solverConstraint = m_tmpSolverContactFrictionConstraintPool.expand();
+ memset(&solverConstraint,0xff,sizeof(btSolverConstraint));
solverConstraint.m_contactNormal = normalAxis;
solverConstraint.m_solverBodyIdA = solverBodyIdA;
solverConstraint.m_solverBodyIdB = solverBodyIdB;
- solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_FRICTION_1D;
solverConstraint.m_frictionIndex = frictionIndex;
solverConstraint.m_friction = cp.m_combinedFriction;
solverConstraint.m_originalContactPoint = 0;
- solverConstraint.m_appliedImpulse = btScalar(0.);
- solverConstraint.m_appliedPushImpulse = 0.f;
- solverConstraint.m_penetration = 0.f;
+ solverConstraint.m_appliedImpulse = 0.f;
+ // solverConstraint.m_appliedPushImpulse = 0.f;
+
{
btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal);
solverConstraint.m_relpos1CrossNormal = ftorqueAxis1;
- solverConstraint.m_angularComponentA = body0 ? body0->getInvInertiaTensorWorld()*ftorqueAxis1 : btVector3(0,0,0);
+ solverConstraint.m_angularComponentA = body0 ? body0->getInvInertiaTensorWorld()*ftorqueAxis1*body0->getAngularFactor() : btVector3(0,0,0);
}
{
- btVector3 ftorqueAxis1 = rel_pos2.cross(solverConstraint.m_contactNormal);
+ btVector3 ftorqueAxis1 = rel_pos2.cross(-solverConstraint.m_contactNormal);
solverConstraint.m_relpos2CrossNormal = ftorqueAxis1;
- solverConstraint.m_angularComponentB = body1 ? body1->getInvInertiaTensorWorld()*ftorqueAxis1 : btVector3(0,0,0);
+ solverConstraint.m_angularComponentB = body1 ? body1->getInvInertiaTensorWorld()*ftorqueAxis1*body1->getAngularFactor() : btVector3(0,0,0);
}
#ifdef COMPUTE_IMPULSE_DENOM
@@ -483,7 +305,7 @@ void btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3&
}
if (body1)
{
- vec = ( solverConstraint.m_angularComponentB).cross(rel_pos2);
+ vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2);
denom1 = body1->getInvMass() + normalAxis.dot(vec);
}
@@ -492,377 +314,499 @@ void btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3&
btScalar denom = relaxation/(denom0+denom1);
solverConstraint.m_jacDiagABInv = denom;
+#ifdef _USE_JACOBIAN
+ solverConstraint.m_jac = btJacobianEntry (
+ rel_pos1,rel_pos2,solverConstraint.m_contactNormal,
+ body0->getInvInertiaDiagLocal(),
+ body0->getInvMass(),
+ body1->getInvInertiaDiagLocal(),
+ body1->getInvMass());
+#endif //_USE_JACOBIAN
-}
+ {
+ btScalar rel_vel;
+ btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(body0?body0->getLinearVelocity():btVector3(0,0,0))
+ + solverConstraint.m_relpos1CrossNormal.dot(body0?body0->getAngularVelocity():btVector3(0,0,0));
+ btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(body1?body1->getLinearVelocity():btVector3(0,0,0))
+ + solverConstraint.m_relpos2CrossNormal.dot(body1?body1->getAngularVelocity():btVector3(0,0,0));
+
+ rel_vel = vel1Dotn+vel2Dotn;
-void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection);
-void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection)
+ btScalar positionalError = 0.f;
+
+ btSimdScalar velocityError = - rel_vel;
+ btSimdScalar velocityImpulse = velocityError * btSimdScalar(solverConstraint.m_jacDiagABInv);
+ solverConstraint.m_rhs = velocityImpulse;
+ solverConstraint.m_cfm = 0.f;
+ solverConstraint.m_lowerLimit = 0;
+ solverConstraint.m_upperLimit = 1e10f;
+ }
+
+ return solverConstraint;
+}
+
+int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& body)
{
- if (colObj && colObj->hasAnisotropicFriction())
+ int solverBodyIdA = -1;
+
+ if (body.getCompanionId() >= 0)
{
- // transform to local coordinates
- btVector3 loc_lateral = frictionDirection * colObj->getWorldTransform().getBasis();
- const btVector3& friction_scaling = colObj->getAnisotropicFriction();
- //apply anisotropic friction
- loc_lateral *= friction_scaling;
- // ... and transform it back to global coordinates
- frictionDirection = colObj->getWorldTransform().getBasis() * loc_lateral;
+ //body has already been converted
+ solverBodyIdA = body.getCompanionId();
+ } else
+ {
+ btRigidBody* rb = btRigidBody::upcast(&body);
+ if (rb && rb->getInvMass())
+ {
+ solverBodyIdA = m_tmpSolverBodyPool.size();
+ btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
+ initSolverBody(&solverBody,&body);
+ body.setCompanionId(solverBodyIdA);
+ } else
+ {
+ return 0;//assume first one is a fixed solver body
+ }
}
+ return solverBodyIdA;
}
+#include <stdio.h>
-
-btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** /*bodies */,int /*numBodies */,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
+void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal)
{
- BT_PROFILE("solveGroupCacheFriendlySetup");
- (void)stackAlloc;
- (void)debugDrawer;
+ btCollisionObject* colObj0=0,*colObj1=0;
+ colObj0 = (btCollisionObject*)manifold->getBody0();
+ colObj1 = (btCollisionObject*)manifold->getBody1();
- if (!(numConstraints + numManifolds))
+ int solverBodyIdA=-1;
+ int solverBodyIdB=-1;
+
+ if (manifold->getNumContacts())
{
-// printf("empty\n");
- return 0.f;
+ solverBodyIdA = getOrInitSolverBody(*colObj0);
+ solverBodyIdB = getOrInitSolverBody(*colObj1);
}
- btPersistentManifold* manifold = 0;
- btCollisionObject* colObj0=0,*colObj1=0;
- //btRigidBody* rb0=0,*rb1=0;
+ ///avoid collision response between two static objects
+ if (!solverBodyIdA && !solverBodyIdB)
+ return;
+ btVector3 rel_pos1;
+ btVector3 rel_pos2;
+ btScalar relaxation;
-#ifdef FORCE_REFESH_CONTACT_MANIFOLDS
+ for (int j=0;j<manifold->getNumContacts();j++)
+ {
- BEGIN_PROFILE("refreshManifolds");
+ btManifoldPoint& cp = manifold->getContactPoint(j);
- int i;
-
-
+ if (cp.getDistance() <= manifold->getContactProcessingThreshold())
+ {
- for (i=0;i<numManifolds;i++)
- {
- manifold = manifoldPtr[i];
- rb1 = (btRigidBody*)manifold->getBody1();
- rb0 = (btRigidBody*)manifold->getBody0();
-
- manifold->refreshContactPoints(rb0->getCenterOfMassTransform(),rb1->getCenterOfMassTransform());
+ const btVector3& pos1 = cp.getPositionWorldOnA();
+ const btVector3& pos2 = cp.getPositionWorldOnB();
- }
+ rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin();
+ rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin();
- END_PROFILE("refreshManifolds");
-#endif //FORCE_REFESH_CONTACT_MANIFOLDS
-
+ relaxation = 1.f;
+ btScalar rel_vel;
+ btVector3 vel;
+ int frictionIndex = m_tmpSolverContactConstraintPool.size();
+ {
+ btSolverConstraint& solverConstraint = m_tmpSolverContactConstraintPool.expand();
+ btRigidBody* rb0 = btRigidBody::upcast(colObj0);
+ btRigidBody* rb1 = btRigidBody::upcast(colObj1);
- //int sizeofSB = sizeof(btSolverBody);
- //int sizeofSC = sizeof(btSolverConstraint);
+ solverConstraint.m_solverBodyIdA = solverBodyIdA;
+ solverConstraint.m_solverBodyIdB = solverBodyIdB;
+ solverConstraint.m_originalContactPoint = &cp;
- //if (1)
- {
- //if m_stackAlloc, try to pack bodies/constraints to speed up solving
-// btBlock* sablock;
-// sablock = stackAlloc->beginBlock();
+ btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB);
+ solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0*rb0->getAngularFactor() : btVector3(0,0,0);
+ btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB);
+ solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*-torqueAxis1*rb1->getAngularFactor() : btVector3(0,0,0);
+ {
+#ifdef COMPUTE_IMPULSE_DENOM
+ btScalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB);
+ btScalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB);
+#else
+ btVector3 vec;
+ btScalar denom0 = 0.f;
+ btScalar denom1 = 0.f;
+ if (rb0)
+ {
+ vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1);
+ denom0 = rb0->getInvMass() + cp.m_normalWorldOnB.dot(vec);
+ }
+ if (rb1)
+ {
+ vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2);
+ denom1 = rb1->getInvMass() + cp.m_normalWorldOnB.dot(vec);
+ }
+#endif //COMPUTE_IMPULSE_DENOM
+
+ btScalar denom = relaxation/(denom0+denom1);
+ solverConstraint.m_jacDiagABInv = denom;
+ }
- // int memsize = 16;
-// unsigned char* stackMemory = stackAlloc->allocate(memsize);
+ solverConstraint.m_contactNormal = cp.m_normalWorldOnB;
+ solverConstraint.m_relpos1CrossNormal = rel_pos1.cross(cp.m_normalWorldOnB);
+ solverConstraint.m_relpos2CrossNormal = rel_pos2.cross(-cp.m_normalWorldOnB);
-
- //todo: use stack allocator for this temp memory
-// int minReservation = numManifolds*2;
- //m_tmpSolverBodyPool.reserve(minReservation);
+ btVector3 vel1 = rb0 ? rb0->getVelocityInLocalPoint(rel_pos1) : btVector3(0,0,0);
+ btVector3 vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0);
- //don't convert all bodies, only the one we need so solver the constraints
-/*
- {
- for (int i=0;i<numBodies;i++)
- {
- btRigidBody* rb = btRigidBody::upcast(bodies[i]);
- if (rb && (rb->getIslandTag() >= 0))
+ vel = vel1 - vel2;
+
+ rel_vel = cp.m_normalWorldOnB.dot(vel);
+
+ btScalar penetration = cp.getDistance()+infoGlobal.m_linearSlop;
+
+
+ solverConstraint.m_friction = cp.m_combinedFriction;
+
+ btScalar restitution = 0.f;
+
+ if (cp.m_lifeTime>infoGlobal.m_restingContactRestitutionThreshold)
{
- btAssert(rb->getCompanionId() < 0);
- int solverBodyId = m_tmpSolverBodyPool.size();
- btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
- initSolverBody(&solverBody,rb);
- rb->setCompanionId(solverBodyId);
- }
- }
- }
-*/
-
- //m_tmpSolverConstraintPool.reserve(minReservation);
- //m_tmpSolverFrictionConstraintPool.reserve(minReservation);
+ restitution = 0.f;
+ } else
+ {
+ restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution);
+ if (restitution <= btScalar(0.))
+ {
+ restitution = 0.f;
+ };
+ }
- {
- int i;
- for (i=0;i<numManifolds;i++)
- {
- manifold = manifoldPtr[i];
- colObj0 = (btCollisionObject*)manifold->getBody0();
- colObj1 = (btCollisionObject*)manifold->getBody1();
-
- int solverBodyIdA=-1;
- int solverBodyIdB=-1;
+ ///warm starting (or zero if disabled)
+ if (0)//infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
+ {
+ solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor;
+ if (rb0)
+ m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].applyImpulse(solverConstraint.m_contactNormal*rb0->getInvMass()*rb0->getLinearFactor(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse);
+ if (rb1)
+ m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].applyImpulse(solverConstraint.m_contactNormal*rb1->getInvMass()*rb1->getLinearFactor(),-solverConstraint.m_angularComponentB,-solverConstraint.m_appliedImpulse);
+ } else
+ {
+ solverConstraint.m_appliedImpulse = 0.f;
+ }
+
+ // solverConstraint.m_appliedPushImpulse = 0.f;
- if (manifold->getNumContacts())
{
+ btScalar rel_vel;
+ btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rb0?rb0->getLinearVelocity():btVector3(0,0,0))
+ + solverConstraint.m_relpos1CrossNormal.dot(rb0?rb0->getAngularVelocity():btVector3(0,0,0));
+ btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rb1?rb1->getLinearVelocity():btVector3(0,0,0))
+ + solverConstraint.m_relpos2CrossNormal.dot(rb1?rb1->getAngularVelocity():btVector3(0,0,0));
+
+ rel_vel = vel1Dotn+vel2Dotn;
+
+ btScalar positionalError = 0.f;
+ positionalError = -penetration * infoGlobal.m_erp/infoGlobal.m_timeStep;
+ btScalar velocityError = restitution - rel_vel;// * damping;
+ btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
+ btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
+ solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
+ solverConstraint.m_cfm = 0.f;
+ solverConstraint.m_lowerLimit = 0;
+ solverConstraint.m_upperLimit = 1e10f;
+ }
-
- if (colObj0->getIslandTag() >= 0)
+ /////setup the friction constraints
+
+
+
+ if (1)
+ {
+ solverConstraint.m_frictionIndex = m_tmpSolverContactFrictionConstraintPool.size();
+ if (!(infoGlobal.m_solverMode & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING) || !cp.m_lateralFrictionInitialized)
{
- if (colObj0->getCompanionId() >= 0)
+ cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel;
+ btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2();
+ if (!(infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > SIMD_EPSILON)
{
- //body has already been converted
- solverBodyIdA = colObj0->getCompanionId();
+ cp.m_lateralFrictionDir1 /= btSqrt(lat_rel_vel);
+ applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1);
+ applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1);
+ addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+ if((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
+ {
+ cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB);
+ cp.m_lateralFrictionDir2.normalize();//??
+ applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2);
+ applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2);
+ addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+ }
+ cp.m_lateralFrictionInitialized = true;
} else
{
- solverBodyIdA = m_tmpSolverBodyPool.size();
- btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
- initSolverBody(&solverBody,colObj0);
- colObj0->setCompanionId(solverBodyIdA);
+ //re-calculate friction direction every frame, todo: check if this is really needed
+ btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2);
+ applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1);
+ applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1);
+
+ addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+ if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
+ {
+ applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2);
+ applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2);
+ addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+ }
+ cp.m_lateralFrictionInitialized = true;
}
+
} else
{
- //create a static body
- solverBodyIdA = m_tmpSolverBodyPool.size();
- btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
- initSolverBody(&solverBody,colObj0);
+ addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+ if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
+ addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
}
- if (colObj1->getIslandTag() >= 0)
+ if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING)
{
- if (colObj1->getCompanionId() >= 0)
{
- solverBodyIdB = colObj1->getCompanionId();
- } else
+ btSolverConstraint& frictionConstraint1 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex];
+ if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
+ {
+ frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor;
+ if (rb0)
+ m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].applyImpulse(frictionConstraint1.m_contactNormal*rb0->getInvMass()*rb0->getLinearFactor(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse);
+ if (rb1)
+ m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].applyImpulse(frictionConstraint1.m_contactNormal*rb1->getInvMass()*rb1->getLinearFactor(),-frictionConstraint1.m_angularComponentB,-frictionConstraint1.m_appliedImpulse);
+ } else
+ {
+ frictionConstraint1.m_appliedImpulse = 0.f;
+ }
+ }
+
+ if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
{
- solverBodyIdB = m_tmpSolverBodyPool.size();
- btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
- initSolverBody(&solverBody,colObj1);
- colObj1->setCompanionId(solverBodyIdB);
+ btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex+1];
+ if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
+ {
+ frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor;
+ if (rb0)
+ m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].applyImpulse(frictionConstraint2.m_contactNormal*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse);
+ if (rb1)
+ m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].applyImpulse(frictionConstraint2.m_contactNormal*rb1->getInvMass(),-frictionConstraint2.m_angularComponentB,-frictionConstraint2.m_appliedImpulse);
+ } else
+ {
+ frictionConstraint2.m_appliedImpulse = 0.f;
+ }
}
} else
{
- //create a static body
- solverBodyIdB = m_tmpSolverBodyPool.size();
- btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
- initSolverBody(&solverBody,colObj1);
+ btSolverConstraint& frictionConstraint1 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex];
+ frictionConstraint1.m_appliedImpulse = 0.f;
+ if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
+ {
+ btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex+1];
+ frictionConstraint2.m_appliedImpulse = 0.f;
+ }
}
}
+ }
- btVector3 rel_pos1;
- btVector3 rel_pos2;
- btScalar relaxation;
- for (int j=0;j<manifold->getNumContacts();j++)
- {
-
- btManifoldPoint& cp = manifold->getContactPoint(j);
-
- if (cp.getDistance() <= btScalar(0.))
- {
-
- const btVector3& pos1 = cp.getPositionWorldOnA();
- const btVector3& pos2 = cp.getPositionWorldOnB();
+ }
+ }
+}
- rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin();
- rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin();
-
- relaxation = 1.f;
- btScalar rel_vel;
- btVector3 vel;
+btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** /*bodies */,int /*numBodies */,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
+{
+ BT_PROFILE("solveGroupCacheFriendlySetup");
+ (void)stackAlloc;
+ (void)debugDrawer;
- int frictionIndex = m_tmpSolverConstraintPool.size();
- {
- btSolverConstraint& solverConstraint = m_tmpSolverConstraintPool.expand();
- btRigidBody* rb0 = btRigidBody::upcast(colObj0);
- btRigidBody* rb1 = btRigidBody::upcast(colObj1);
+ if (!(numConstraints + numManifolds))
+ {
+ // printf("empty\n");
+ return 0.f;
+ }
- solverConstraint.m_solverBodyIdA = solverBodyIdA;
- solverConstraint.m_solverBodyIdB = solverBodyIdB;
- solverConstraint.m_constraintType = btSolverConstraint::BT_SOLVER_CONTACT_1D;
+ if (1)
+ {
+ int j;
+ for (j=0;j<numConstraints;j++)
+ {
+ btTypedConstraint* constraint = constraints[j];
+ constraint->buildJacobian();
+ }
+ }
- solverConstraint.m_originalContactPoint = &cp;
+ btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
+ initSolverBody(&fixedBody,0);
- btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB);
- solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0 : btVector3(0,0,0);
- btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB);
- solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*torqueAxis1 : btVector3(0,0,0);
- {
-#ifdef COMPUTE_IMPULSE_DENOM
- btScalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB);
- btScalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB);
-#else
- btVector3 vec;
- btScalar denom0 = 0.f;
- btScalar denom1 = 0.f;
- if (rb0)
- {
- vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1);
- denom0 = rb0->getInvMass() + cp.m_normalWorldOnB.dot(vec);
- }
- if (rb1)
- {
- vec = ( solverConstraint.m_angularComponentB).cross(rel_pos2);
- denom1 = rb1->getInvMass() + cp.m_normalWorldOnB.dot(vec);
- }
-#endif //COMPUTE_IMPULSE_DENOM
-
- btScalar denom = relaxation/(denom0+denom1);
- solverConstraint.m_jacDiagABInv = denom;
- }
+ //btRigidBody* rb0=0,*rb1=0;
- solverConstraint.m_contactNormal = cp.m_normalWorldOnB;
- solverConstraint.m_relpos1CrossNormal = rel_pos1.cross(cp.m_normalWorldOnB);
- solverConstraint.m_relpos2CrossNormal = rel_pos2.cross(cp.m_normalWorldOnB);
+ //if (1)
+ {
+ {
+ int totalNumRows = 0;
+ int i;
+ //calculate the total number of contraint rows
+ for (i=0;i<numConstraints;i++)
+ {
- btVector3 vel1 = rb0 ? rb0->getVelocityInLocalPoint(rel_pos1) : btVector3(0,0,0);
- btVector3 vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0);
-
- vel = vel1 - vel2;
-
- rel_vel = cp.m_normalWorldOnB.dot(vel);
-
- solverConstraint.m_penetration = btMin(cp.getDistance()+infoGlobal.m_linearSlop,btScalar(0.));
- //solverConstraint.m_penetration = cp.getDistance();
-
- solverConstraint.m_friction = cp.m_combinedFriction;
- solverConstraint.m_restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution);
- if (solverConstraint.m_restitution <= btScalar(0.))
- {
- solverConstraint.m_restitution = 0.f;
- };
+ btTypedConstraint::btConstraintInfo1 info1;
+ constraints[i]->getInfo1(&info1);
+ totalNumRows += info1.m_numConstraintRows;
+ }
+ m_tmpSolverNonContactConstraintPool.resize(totalNumRows);
-
- btScalar penVel = -solverConstraint.m_penetration/infoGlobal.m_timeStep;
+ btTypedConstraint::btConstraintInfo1 info1;
+ info1.m_numConstraintRows = 0;
-
- if (solverConstraint.m_restitution > penVel)
- {
- solverConstraint.m_penetration = btScalar(0.);
- }
-
-
-
- ///warm starting (or zero if disabled)
- if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
- {
- solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor;
- if (rb0)
- m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(solverConstraint.m_contactNormal*rb0->getInvMass(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse);
- if (rb1)
- m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(solverConstraint.m_contactNormal*rb1->getInvMass(),solverConstraint.m_angularComponentB,-solverConstraint.m_appliedImpulse);
- } else
- {
- solverConstraint.m_appliedImpulse = 0.f;
- }
+ ///setup the btSolverConstraints
+ int currentRow = 0;
- solverConstraint.m_appliedPushImpulse = 0.f;
-
- solverConstraint.m_frictionIndex = m_tmpSolverFrictionConstraintPool.size();
- if (!cp.m_lateralFrictionInitialized)
- {
- cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel;
-
- //scale anisotropic friction
-
- applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1);
- applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1);
-
- btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2();
-
-
- if (lat_rel_vel > SIMD_EPSILON)//0.0f)
- {
- cp.m_lateralFrictionDir1 /= btSqrt(lat_rel_vel);
- addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
- cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB);
- cp.m_lateralFrictionDir2.normalize();
- applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2);
- applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2);
-
- addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
- } else
- {
- //re-calculate friction direction every frame, todo: check if this is really needed
- btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2);
- applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2);
- applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2);
- addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
- addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
- }
- cp.m_lateralFrictionInitialized = true;
-
- } else
- {
- addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
- addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
- }
+ for (i=0;i<numConstraints;i++,currentRow+=info1.m_numConstraintRows)
+ {
+ constraints[i]->getInfo1(&info1);
+ if (info1.m_numConstraintRows)
+ {
+ btAssert(currentRow<totalNumRows);
- {
- btSolverConstraint& frictionConstraint1 = m_tmpSolverFrictionConstraintPool[solverConstraint.m_frictionIndex];
- if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
- {
- frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor;
- if (rb0)
- m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(frictionConstraint1.m_contactNormal*rb0->getInvMass(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse);
- if (rb1)
- m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(frictionConstraint1.m_contactNormal*rb1->getInvMass(),frictionConstraint1.m_angularComponentB,-frictionConstraint1.m_appliedImpulse);
- } else
- {
- frictionConstraint1.m_appliedImpulse = 0.f;
- }
- }
- {
- btSolverConstraint& frictionConstraint2 = m_tmpSolverFrictionConstraintPool[solverConstraint.m_frictionIndex+1];
- if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
- {
- frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor;
- if (rb0)
- m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(frictionConstraint2.m_contactNormal*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse);
- if (rb1)
- m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(frictionConstraint2.m_contactNormal*rb1->getInvMass(),frictionConstraint2.m_angularComponentB,-frictionConstraint2.m_appliedImpulse);
- } else
- {
- frictionConstraint2.m_appliedImpulse = 0.f;
- }
- }
+ btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow];
+ btTypedConstraint* constraint = constraints[i];
+
+
+
+ btRigidBody& rbA = constraint->getRigidBodyA();
+ btRigidBody& rbB = constraint->getRigidBodyB();
+
+ int solverBodyIdA = getOrInitSolverBody(rbA);
+ int solverBodyIdB = getOrInitSolverBody(rbB);
+
+ btSolverBody* bodyAPtr = &m_tmpSolverBodyPool[solverBodyIdA];
+ btSolverBody* bodyBPtr = &m_tmpSolverBodyPool[solverBodyIdB];
+
+ int j;
+ for ( j=0;j<info1.m_numConstraintRows;j++)
+ {
+ memset(&currentConstraintRow[j],0,sizeof(btSolverConstraint));
+ currentConstraintRow[j].m_lowerLimit = -FLT_MAX;
+ currentConstraintRow[j].m_upperLimit = FLT_MAX;
+ currentConstraintRow[j].m_appliedImpulse = 0.f;
+ currentConstraintRow[j].m_appliedPushImpulse = 0.f;
+ currentConstraintRow[j].m_solverBodyIdA = solverBodyIdA;
+ currentConstraintRow[j].m_solverBodyIdB = solverBodyIdB;
+ }
+
+ bodyAPtr->m_deltaLinearVelocity.setValue(0.f,0.f,0.f);
+ bodyAPtr->m_deltaAngularVelocity.setValue(0.f,0.f,0.f);
+ bodyBPtr->m_deltaLinearVelocity.setValue(0.f,0.f,0.f);
+ bodyBPtr->m_deltaAngularVelocity.setValue(0.f,0.f,0.f);
+
+
+
+ btTypedConstraint::btConstraintInfo2 info2;
+ info2.fps = 1.f/infoGlobal.m_timeStep;
+ info2.erp = infoGlobal.m_erp;
+ info2.m_J1linearAxis = currentConstraintRow->m_contactNormal;
+ info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal;
+ info2.m_J2linearAxis = 0;
+ info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal;
+ info2.rowskip = sizeof(btSolverConstraint)/sizeof(btScalar);//check this
+ ///the size of btSolverConstraint needs be a multiple of btScalar
+ btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint));
+ info2.m_constraintError = &currentConstraintRow->m_rhs;
+ info2.cfm = &currentConstraintRow->m_cfm;
+ info2.m_lowerLimit = &currentConstraintRow->m_lowerLimit;
+ info2.m_upperLimit = &currentConstraintRow->m_upperLimit;
+ constraints[i]->getInfo2(&info2);
+
+ ///finalize the constraint setup
+ for ( j=0;j<info1.m_numConstraintRows;j++)
+ {
+ btSolverConstraint& solverConstraint = currentConstraintRow[j];
+
+ {
+ const btVector3& ftorqueAxis1 = solverConstraint.m_relpos1CrossNormal;
+ solverConstraint.m_angularComponentA = constraint->getRigidBodyA().getInvInertiaTensorWorld()*ftorqueAxis1*constraint->getRigidBodyA().getAngularFactor();
+ }
+ {
+ const btVector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal;
+ solverConstraint.m_angularComponentB = constraint->getRigidBodyB().getInvInertiaTensorWorld()*ftorqueAxis2*constraint->getRigidBodyB().getAngularFactor();
+ }
+
+ {
+ btVector3 iMJlA = solverConstraint.m_contactNormal*rbA.getInvMass();
+ btVector3 iMJaA = rbA.getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal;
+ btVector3 iMJlB = solverConstraint.m_contactNormal*rbB.getInvMass();//sign of normal?
+ btVector3 iMJaB = rbB.getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal;
+
+ btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal);
+ sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal);
+ sum += iMJlB.dot(solverConstraint.m_contactNormal);
+ sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal);
+
+ solverConstraint.m_jacDiagABInv = btScalar(1.)/sum;
}
+ ///fix rhs
+ ///todo: add force/torque accelerators
+ {
+ btScalar rel_vel;
+ btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rbA.getLinearVelocity()) + solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity());
+ btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rbB.getLinearVelocity()) + solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity());
+
+ rel_vel = vel1Dotn+vel2Dotn;
+
+ btScalar restitution = 0.f;
+ btScalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2
+ btScalar velocityError = restitution - rel_vel;// * damping;
+ btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
+ btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
+ solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
+ solverConstraint.m_appliedImpulse = 0.f;
+
+ }
}
}
}
}
- }
-
- btContactSolverInfo info = infoGlobal;
- {
- int j;
- for (j=0;j<numConstraints;j++)
{
- btTypedConstraint* constraint = constraints[j];
- constraint->buildJacobian();
+ int i;
+ btPersistentManifold* manifold = 0;
+ btCollisionObject* colObj0=0,*colObj1=0;
+
+
+ for (i=0;i<numManifolds;i++)
+ {
+ manifold = manifoldPtr[i];
+ convertContact(manifold,infoGlobal);
+ }
}
}
-
-
- int numConstraintPool = m_tmpSolverConstraintPool.size();
- int numFrictionPool = m_tmpSolverFrictionConstraintPool.size();
+ btContactSolverInfo info = infoGlobal;
+
- ///todo: use stack allocator for such temporarily memory, same for solver bodies/constraints
+
+ int numConstraintPool = m_tmpSolverContactConstraintPool.size();
+ int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size();
+
+ ///@todo: use stack allocator for such temporarily memory, same for solver bodies/constraints
m_orderTmpConstraintPool.resize(numConstraintPool);
m_orderFrictionConstraintPool.resize(numFrictionPool);
{
@@ -877,8 +821,6 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
}
}
-
-
return 0.f;
}
@@ -886,8 +828,9 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(btCollisionObject** /*bodies */,int /*numBodies*/,btPersistentManifold** /*manifoldPtr*/, int /*numManifolds*/,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* /*debugDrawer*/,btStackAlloc* /*stackAlloc*/)
{
BT_PROFILE("solveGroupCacheFriendlyIterations");
- int numConstraintPool = m_tmpSolverConstraintPool.size();
- int numFrictionPool = m_tmpSolverFrictionConstraintPool.size();
+
+ int numConstraintPool = m_tmpSolverContactConstraintPool.size();
+ int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size();
//should traverse the contacts random order...
int iteration;
@@ -915,110 +858,134 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(
}
}
- for (j=0;j<numConstraints;j++)
+ if (infoGlobal.m_solverMode & SOLVER_SIMD)
{
- btTypedConstraint* constraint = constraints[j];
- ///todo: use solver bodies, so we don't need to copy from/to btRigidBody
-
- if ((constraint->getRigidBodyA().getIslandTag() >= 0) && (constraint->getRigidBodyA().getCompanionId() >= 0))
+ ///solve all joint constraints, using SIMD, if available
+ for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
{
- m_tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].writebackVelocity();
+ btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[j];
+ resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[constraint.m_solverBodyIdA],m_tmpSolverBodyPool[constraint.m_solverBodyIdB],constraint);
}
- if ((constraint->getRigidBodyB().getIslandTag() >= 0) && (constraint->getRigidBodyB().getCompanionId() >= 0))
+
+ for (j=0;j<numConstraints;j++)
{
- m_tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].writebackVelocity();
+ int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA());
+ int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB());
+ btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid];
+ btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid];
+ constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep);
}
- constraint->solveConstraint(infoGlobal.m_timeStep);
-
- if ((constraint->getRigidBodyA().getIslandTag() >= 0) && (constraint->getRigidBodyA().getCompanionId() >= 0))
+ ///solve all contact constraints using SIMD, if available
+ int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
+ for (j=0;j<numPoolConstraints;j++)
{
- m_tmpSolverBodyPool[constraint->getRigidBodyA().getCompanionId()].readVelocity();
+ const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
+ resolveSingleConstraintRowLowerLimitSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
+
}
- if ((constraint->getRigidBodyB().getIslandTag() >= 0) && (constraint->getRigidBodyB().getCompanionId() >= 0))
+ ///solve all friction constraints, using SIMD, if available
+ int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
+ for (j=0;j<numFrictionPoolConstraints;j++)
{
- m_tmpSolverBodyPool[constraint->getRigidBodyB().getCompanionId()].readVelocity();
- }
+ btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
+ btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
- }
+ if (totalImpulse>btScalar(0))
+ {
+ solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
+ solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
+ resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
+ }
+ }
+ } else
{
- int numPoolConstraints = m_tmpSolverConstraintPool.size();
- for (j=0;j<numPoolConstraints;j++)
+
+ ///solve all joint constraints
+ for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
{
-
- const btSolverConstraint& solveManifold = m_tmpSolverConstraintPool[m_orderTmpConstraintPool[j]];
- resolveSingleCollisionCombinedCacheFriendly(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],
- m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold,infoGlobal);
+ btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[j];
+ resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[constraint.m_solverBodyIdA],m_tmpSolverBodyPool[constraint.m_solverBodyIdB],constraint);
}
- }
- {
- int numFrictionPoolConstraints = m_tmpSolverFrictionConstraintPool.size();
-
- for (j=0;j<numFrictionPoolConstraints;j++)
+ for (j=0;j<numConstraints;j++)
{
- const btSolverConstraint& solveManifold = m_tmpSolverFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
- btScalar totalImpulse = m_tmpSolverConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse+
- m_tmpSolverConstraintPool[solveManifold.m_frictionIndex].m_appliedPushImpulse;
+ int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA());
+ int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB());
+ btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid];
+ btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid];
- resolveSingleFrictionCacheFriendly(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],
- m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold,infoGlobal,
- totalImpulse);
+ constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep);
}
- }
-
-
- }
-
- if (infoGlobal.m_splitImpulse)
- {
-
- for ( iteration = 0;iteration<infoGlobal.m_numIterations;iteration++)
- {
+ ///solve all contact constraints
+ int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
+ for (j=0;j<numPoolConstraints;j++)
{
- int numPoolConstraints = m_tmpSolverConstraintPool.size();
- int j;
- for (j=0;j<numPoolConstraints;j++)
+ const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
+ resolveSingleConstraintRowLowerLimit(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
+ }
+ ///solve all friction constraints
+ int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
+ for (j=0;j<numFrictionPoolConstraints;j++)
+ {
+ btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
+ btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
+
+ if (totalImpulse>btScalar(0))
{
- const btSolverConstraint& solveManifold = m_tmpSolverConstraintPool[m_orderTmpConstraintPool[j]];
+ solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
+ solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
- resolveSplitPenetrationImpulseCacheFriendly(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],
- m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold,infoGlobal);
+ resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
}
}
}
- }
- }
+ }
+ }
return 0.f;
}
-btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc)
+
+/// btSequentialImpulseConstraintSolver Sequentially applies impulses
+btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc,btDispatcher* /*dispatcher*/)
{
+
+
+
+ BT_PROFILE("solveGroup");
+ //we only implement SOLVER_CACHE_FRIENDLY now
+ //you need to provide at least some bodies
+ btAssert(bodies);
+ btAssert(numBodies);
+
int i;
solveGroupCacheFriendlySetup( bodies, numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
solveGroupCacheFriendlyIterations(bodies, numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
- int numPoolConstraints = m_tmpSolverConstraintPool.size();
+ int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
int j;
+
for (j=0;j<numPoolConstraints;j++)
{
-
- const btSolverConstraint& solveManifold = m_tmpSolverConstraintPool[j];
+
+ const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[j];
btManifoldPoint* pt = (btManifoldPoint*) solveManifold.m_originalContactPoint;
btAssert(pt);
pt->m_appliedImpulse = solveManifold.m_appliedImpulse;
- pt->m_appliedImpulseLateral1 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
- pt->m_appliedImpulseLateral2 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse;
+ if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING)
+ {
+ pt->m_appliedImpulseLateral1 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
+ pt->m_appliedImpulseLateral2 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse;
+ }
//do a callback here?
-
}
if (infoGlobal.m_splitImpulse)
@@ -1030,418 +997,26 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendly(btCollisio
} else
{
for ( i=0;i<m_tmpSolverBodyPool.size();i++)
- {
- m_tmpSolverBodyPool[i].writebackVelocity();
- }
- }
-
-// printf("m_tmpSolverConstraintPool.size() = %i\n",m_tmpSolverConstraintPool.size());
-
-/*
- printf("m_tmpSolverBodyPool.size() = %i\n",m_tmpSolverBodyPool.size());
- printf("m_tmpSolverConstraintPool.size() = %i\n",m_tmpSolverConstraintPool.size());
- printf("m_tmpSolverFrictionConstraintPool.size() = %i\n",m_tmpSolverFrictionConstraintPool.size());
-
-
- printf("m_tmpSolverBodyPool.capacity() = %i\n",m_tmpSolverBodyPool.capacity());
- printf("m_tmpSolverConstraintPool.capacity() = %i\n",m_tmpSolverConstraintPool.capacity());
- printf("m_tmpSolverFrictionConstraintPool.capacity() = %i\n",m_tmpSolverFrictionConstraintPool.capacity());
-*/
-
- m_tmpSolverBodyPool.resize(0);
- m_tmpSolverConstraintPool.resize(0);
- m_tmpSolverFrictionConstraintPool.resize(0);
-
-
- return 0.f;
-}
-
-/// btSequentialImpulseConstraintSolver Sequentially applies impulses
-btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc,btDispatcher* /*dispatcher*/)
-{
- BT_PROFILE("solveGroup");
- if (infoGlobal.m_solverMode & SOLVER_CACHE_FRIENDLY)
- {
- //you need to provide at least some bodies
- //btSimpleDynamicsWorld needs to switch off SOLVER_CACHE_FRIENDLY
- btAssert(bodies);
- btAssert(numBodies);
- return solveGroupCacheFriendly(bodies,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer,stackAlloc);
- }
-
-
-
- btContactSolverInfo info = infoGlobal;
-
- int numiter = infoGlobal.m_numIterations;
-
- int totalPoints = 0;
-
-
- {
- short j;
- for (j=0;j<numManifolds;j++)
- {
- btPersistentManifold* manifold = manifoldPtr[j];
- prepareConstraints(manifold,info,debugDrawer);
-
- for (short p=0;p<manifoldPtr[j]->getNumContacts();p++)
- {
- gOrder[totalPoints].m_manifoldIndex = j;
- gOrder[totalPoints].m_pointIndex = p;
- totalPoints++;
- }
- }
- }
-
- {
- int j;
- for (j=0;j<numConstraints;j++)
- {
- btTypedConstraint* constraint = constraints[j];
- constraint->buildJacobian();
- }
- }
-
-
- //should traverse the contacts random order...
- int iteration;
-
- {
- for ( iteration = 0;iteration<numiter;iteration++)
- {
- int j;
- if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER)
- {
- if ((iteration & 7) == 0) {
- for (j=0; j<totalPoints; ++j) {
- btOrderIndex tmp = gOrder[j];
- int swapi = btRandInt2(j+1);
- gOrder[j] = gOrder[swapi];
- gOrder[swapi] = tmp;
- }
- }
- }
-
- for (j=0;j<numConstraints;j++)
- {
- btTypedConstraint* constraint = constraints[j];
- constraint->solveConstraint(info.m_timeStep);
- }
-
- for (j=0;j<totalPoints;j++)
- {
- btPersistentManifold* manifold = manifoldPtr[gOrder[j].m_manifoldIndex];
- solve( (btRigidBody*)manifold->getBody0(),
- (btRigidBody*)manifold->getBody1()
- ,manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer);
- }
-
- for (j=0;j<totalPoints;j++)
- {
- btPersistentManifold* manifold = manifoldPtr[gOrder[j].m_manifoldIndex];
- solveFriction((btRigidBody*)manifold->getBody0(),
- (btRigidBody*)manifold->getBody1(),manifold->getContactPoint(gOrder[j].m_pointIndex),info,iteration,debugDrawer);
- }
-
- }
- }
-
-
-
-
- return btScalar(0.);
-}
-
-
-
-
-
-
-
-void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifold* manifoldPtr, const btContactSolverInfo& info,btIDebugDraw* debugDrawer)
-{
-
- (void)debugDrawer;
-
- btRigidBody* body0 = (btRigidBody*)manifoldPtr->getBody0();
- btRigidBody* body1 = (btRigidBody*)manifoldPtr->getBody1();
-
-
- //only necessary to refresh the manifold once (first iteration). The integration is done outside the loop
- {
-#ifdef FORCE_REFESH_CONTACT_MANIFOLDS
- manifoldPtr->refreshContactPoints(body0->getCenterOfMassTransform(),body1->getCenterOfMassTransform());
-#endif //FORCE_REFESH_CONTACT_MANIFOLDS
- int numpoints = manifoldPtr->getNumContacts();
-
- gTotalContactPoints += numpoints;
-
-
- for (int i=0;i<numpoints ;i++)
- {
- btManifoldPoint& cp = manifoldPtr->getContactPoint(i);
- if (cp.getDistance() <= btScalar(0.))
- {
- const btVector3& pos1 = cp.getPositionWorldOnA();
- const btVector3& pos2 = cp.getPositionWorldOnB();
-
- btVector3 rel_pos1 = pos1 - body0->getCenterOfMassPosition();
- btVector3 rel_pos2 = pos2 - body1->getCenterOfMassPosition();
-
-
- //this jacobian entry is re-used for all iterations
- btJacobianEntry jac(body0->getCenterOfMassTransform().getBasis().transpose(),
- body1->getCenterOfMassTransform().getBasis().transpose(),
- rel_pos1,rel_pos2,cp.m_normalWorldOnB,body0->getInvInertiaDiagLocal(),body0->getInvMass(),
- body1->getInvInertiaDiagLocal(),body1->getInvMass());
-
-
- btScalar jacDiagAB = jac.getDiagonal();
-
- btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData;
- if (cpd)
- {
- //might be invalid
- cpd->m_persistentLifeTime++;
- if (cpd->m_persistentLifeTime != cp.getLifeTime())
- {
- //printf("Invalid: cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd->m_persistentLifeTime,cp.getLifeTime());
- new (cpd) btConstraintPersistentData;
- cpd->m_persistentLifeTime = cp.getLifeTime();
-
- } else
- {
- //printf("Persistent: cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd->m_persistentLifeTime,cp.getLifeTime());
-
- }
- } else
- {
-
- //todo: should this be in a pool?
- void* mem = btAlignedAlloc(sizeof(btConstraintPersistentData),16);
- cpd = new (mem)btConstraintPersistentData;
- assert(cpd);
-
- totalCpd ++;
- //printf("totalCpd = %i Created Ptr %x\n",totalCpd,cpd);
- cp.m_userPersistentData = cpd;
- cpd->m_persistentLifeTime = cp.getLifeTime();
- //printf("CREATED: %x . cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd,cpd->m_persistentLifeTime,cp.getLifeTime());
-
- }
- assert(cpd);
-
- cpd->m_jacDiagABInv = btScalar(1.) / jacDiagAB;
-
- //Dependent on Rigidbody A and B types, fetch the contact/friction response func
- //perhaps do a similar thing for friction/restutution combiner funcs...
-
- cpd->m_frictionSolverFunc = m_frictionDispatch[body0->m_frictionSolverType][body1->m_frictionSolverType];
- cpd->m_contactSolverFunc = m_contactDispatch[body0->m_contactSolverType][body1->m_contactSolverType];
-
- btVector3 vel1 = body0->getVelocityInLocalPoint(rel_pos1);
- btVector3 vel2 = body1->getVelocityInLocalPoint(rel_pos2);
- btVector3 vel = vel1 - vel2;
- btScalar rel_vel;
- rel_vel = cp.m_normalWorldOnB.dot(vel);
-
- btScalar combinedRestitution = cp.m_combinedRestitution;
-
- cpd->m_penetration = cp.getDistance();///btScalar(info.m_numIterations);
- cpd->m_friction = cp.m_combinedFriction;
- cpd->m_restitution = restitutionCurve(rel_vel, combinedRestitution);
- if (cpd->m_restitution <= btScalar(0.))
- {
- cpd->m_restitution = btScalar(0.0);
-
- };
-
- //restitution and penetration work in same direction so
- //rel_vel
-
- btScalar penVel = -cpd->m_penetration/info.m_timeStep;
-
- if (cpd->m_restitution > penVel)
- {
- cpd->m_penetration = btScalar(0.);
- }
-
-
- btScalar relaxation = info.m_damping;
- if (info.m_solverMode & SOLVER_USE_WARMSTARTING)
- {
- cpd->m_appliedImpulse *= relaxation;
- } else
- {
- cpd->m_appliedImpulse =btScalar(0.);
- }
-
- //for friction
- cpd->m_prevAppliedImpulse = cpd->m_appliedImpulse;
-
- //re-calculate friction direction every frame, todo: check if this is really needed
- btPlaneSpace1(cp.m_normalWorldOnB,cpd->m_frictionWorldTangential0,cpd->m_frictionWorldTangential1);
-
-
-#define NO_FRICTION_WARMSTART 1
-
- #ifdef NO_FRICTION_WARMSTART
- cpd->m_accumulatedTangentImpulse0 = btScalar(0.);
- cpd->m_accumulatedTangentImpulse1 = btScalar(0.);
- #endif //NO_FRICTION_WARMSTART
- btScalar denom0 = body0->computeImpulseDenominator(pos1,cpd->m_frictionWorldTangential0);
- btScalar denom1 = body1->computeImpulseDenominator(pos2,cpd->m_frictionWorldTangential0);
- btScalar denom = relaxation/(denom0+denom1);
- cpd->m_jacDiagABInvTangent0 = denom;
-
-
- denom0 = body0->computeImpulseDenominator(pos1,cpd->m_frictionWorldTangential1);
- denom1 = body1->computeImpulseDenominator(pos2,cpd->m_frictionWorldTangential1);
- denom = relaxation/(denom0+denom1);
- cpd->m_jacDiagABInvTangent1 = denom;
-
- btVector3 totalImpulse =
- #ifndef NO_FRICTION_WARMSTART
- cpd->m_frictionWorldTangential0*cpd->m_accumulatedTangentImpulse0+
- cpd->m_frictionWorldTangential1*cpd->m_accumulatedTangentImpulse1+
- #endif //NO_FRICTION_WARMSTART
- cp.m_normalWorldOnB*cpd->m_appliedImpulse;
-
-
-
- ///
- {
- btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB);
- cpd->m_angularComponentA = body0->getInvInertiaTensorWorld()*torqueAxis0;
- btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB);
- cpd->m_angularComponentB = body1->getInvInertiaTensorWorld()*torqueAxis1;
- }
- {
- btVector3 ftorqueAxis0 = rel_pos1.cross(cpd->m_frictionWorldTangential0);
- cpd->m_frictionAngularComponent0A = body0->getInvInertiaTensorWorld()*ftorqueAxis0;
- }
- {
- btVector3 ftorqueAxis1 = rel_pos1.cross(cpd->m_frictionWorldTangential1);
- cpd->m_frictionAngularComponent1A = body0->getInvInertiaTensorWorld()*ftorqueAxis1;
- }
- {
- btVector3 ftorqueAxis0 = rel_pos2.cross(cpd->m_frictionWorldTangential0);
- cpd->m_frictionAngularComponent0B = body1->getInvInertiaTensorWorld()*ftorqueAxis0;
- }
- {
- btVector3 ftorqueAxis1 = rel_pos2.cross(cpd->m_frictionWorldTangential1);
- cpd->m_frictionAngularComponent1B = body1->getInvInertiaTensorWorld()*ftorqueAxis1;
- }
-
- ///
-
-
-
- //apply previous frames impulse on both bodies
- body0->applyImpulse(totalImpulse, rel_pos1);
- body1->applyImpulse(-totalImpulse, rel_pos2);
- }
-
- }
- }
-}
-
-
-btScalar btSequentialImpulseConstraintSolver::solveCombinedContactFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer)
-{
- btScalar maxImpulse = btScalar(0.);
-
- {
-
-
{
- if (cp.getDistance() <= btScalar(0.))
- {
-
-
-
- {
-
- //btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData;
- btScalar impulse = resolveSingleCollisionCombined(
- *body0,*body1,
- cp,
- info);
-
- if (maxImpulse < impulse)
- maxImpulse = impulse;
-
- }
- }
+ m_tmpSolverBodyPool[i].writebackVelocity();
}
}
- return maxImpulse;
-}
-
-
-
-btScalar btSequentialImpulseConstraintSolver::solve(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer)
-{
-
- btScalar maxImpulse = btScalar(0.);
-
- {
-
-
- {
- if (cp.getDistance() <= btScalar(0.))
- {
-
-
-
- {
- btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData;
- btScalar impulse = cpd->m_contactSolverFunc(
- *body0,*body1,
- cp,
- info);
- if (maxImpulse < impulse)
- maxImpulse = impulse;
+ m_tmpSolverBodyPool.resize(0);
+ m_tmpSolverContactConstraintPool.resize(0);
+ m_tmpSolverNonContactConstraintPool.resize(0);
+ m_tmpSolverContactFrictionConstraintPool.resize(0);
- }
- }
- }
- }
- return maxImpulse;
+ return 0.f;
}
-btScalar btSequentialImpulseConstraintSolver::solveFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer)
-{
- (void)debugDrawer;
- (void)iter;
- {
-
- {
-
- if (cp.getDistance() <= btScalar(0.))
- {
- btConstraintPersistentData* cpd = (btConstraintPersistentData*) cp.m_userPersistentData;
- cpd->m_frictionSolverFunc(
- *body0,*body1,
- cp,
- info);
-
- }
- }
-
-
- }
- return btScalar(0.);
-}
void btSequentialImpulseConstraintSolver::reset()
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
index 7143bc41991..90e7fc8354d 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
@@ -23,67 +23,59 @@ class btIDebugDraw;
#include "btSolverConstraint.h"
-/// btSequentialImpulseConstraintSolver uses a Propagation Method and Sequentially applies impulses
-/// The approach is the 3D version of Erin Catto's GDC 2006 tutorial. See http://www.gphysics.com
-/// Although Sequential Impulse is more intuitive, it is mathematically equivalent to Projected Successive Overrelaxation (iterative LCP)
-/// Applies impulses for combined restitution and penetration recovery and to simulate friction
+
+///The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (iterative LCP) method.
class btSequentialImpulseConstraintSolver : public btConstraintSolver
{
+protected:
btAlignedObjectArray<btSolverBody> m_tmpSolverBodyPool;
- btAlignedObjectArray<btSolverConstraint> m_tmpSolverConstraintPool;
- btAlignedObjectArray<btSolverConstraint> m_tmpSolverFrictionConstraintPool;
+ btConstraintArray m_tmpSolverContactConstraintPool;
+ btConstraintArray m_tmpSolverNonContactConstraintPool;
+ btConstraintArray m_tmpSolverContactFrictionConstraintPool;
btAlignedObjectArray<int> m_orderTmpConstraintPool;
btAlignedObjectArray<int> m_orderFrictionConstraintPool;
-
-protected:
- btScalar solve(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer);
- btScalar solveFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer);
- void prepareConstraints(btPersistentManifold* manifoldPtr, const btContactSolverInfo& info,btIDebugDraw* debugDrawer);
- void addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation);
-
- ContactSolverFunc m_contactDispatch[MAX_CONTACT_SOLVER_TYPES][MAX_CONTACT_SOLVER_TYPES];
- ContactSolverFunc m_frictionDispatch[MAX_CONTACT_SOLVER_TYPES][MAX_CONTACT_SOLVER_TYPES];
-
+ btSolverConstraint& addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation);
///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction
unsigned long m_btSeed2;
-public:
+ void initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject);
+ btScalar restitutionCurve(btScalar rel_vel, btScalar restitution);
-
- btSequentialImpulseConstraintSolver();
+ void convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal);
- ///Advanced: Override the default contact solving function for contacts, for certain types of rigidbody
- ///See btRigidBody::m_contactSolverType and btRigidBody::m_frictionSolverType
- void setContactSolverFunc(ContactSolverFunc func,int type0,int type1)
- {
- m_contactDispatch[type0][type1] = func;
- }
+ void resolveSplitPenetrationImpulseCacheFriendly(
+ btSolverBody& body1,
+ btSolverBody& body2,
+ const btSolverConstraint& contactConstraint,
+ const btContactSolverInfo& solverInfo);
+
+ //internal method
+ int getOrInitSolverBody(btCollisionObject& body);
+
+ void resolveSingleConstraintRowGeneric(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);
+
+ void resolveSingleConstraintRowGenericSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);
- ///Advanced: Override the default friction solving function for contacts, for certain types of rigidbody
- ///See btRigidBody::m_contactSolverType and btRigidBody::m_frictionSolverType
- void SetFrictionSolverFunc(ContactSolverFunc func,int type0,int type1)
- {
- m_frictionDispatch[type0][type1] = func;
- }
+ void resolveSingleConstraintRowLowerLimit(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);
+
+ void resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);
+
+public:
- virtual ~btSequentialImpulseConstraintSolver();
- virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher);
+ btSequentialImpulseConstraintSolver();
+ virtual ~btSequentialImpulseConstraintSolver();
- virtual btScalar solveGroupCacheFriendly(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
- btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
+ virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher);
+
btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
-
+ btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
///clear internal cached data and reset random seed
virtual void reset();
-
- btScalar solveCombinedContactFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer);
-
-
unsigned long btRand2();
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
index 4128f504bf1..50d06960379 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
@@ -68,7 +68,9 @@ void btSliderConstraint::initParams()
btSliderConstraint::btSliderConstraint()
:btTypedConstraint(SLIDER_CONSTRAINT_TYPE),
- m_useLinearReferenceFrameA(true)
+ m_useLinearReferenceFrameA(true),
+ m_useSolveConstraintObsolete(false)
+// m_useSolveConstraintObsolete(true)
{
initParams();
} // btSliderConstraint::btSliderConstraint()
@@ -79,7 +81,9 @@ btSliderConstraint::btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const
: btTypedConstraint(SLIDER_CONSTRAINT_TYPE, rbA, rbB)
, m_frameInA(frameInA)
, m_frameInB(frameInB),
- m_useLinearReferenceFrameA(useLinearReferenceFrameA)
+ m_useLinearReferenceFrameA(useLinearReferenceFrameA),
+ m_useSolveConstraintObsolete(false)
+// m_useSolveConstraintObsolete(true)
{
initParams();
} // btSliderConstraint::btSliderConstraint()
@@ -88,6 +92,10 @@ btSliderConstraint::btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const
void btSliderConstraint::buildJacobian()
{
+ if (!m_useSolveConstraintObsolete)
+ {
+ return;
+ }
if(m_useLinearReferenceFrameA)
{
buildJacobianInt(m_rbA, m_rbB, m_frameInA, m_frameInB);
@@ -155,27 +163,372 @@ void btSliderConstraint::buildJacobianInt(btRigidBody& rbA, btRigidBody& rbB, co
//-----------------------------------------------------------------------------
-void btSliderConstraint::solveConstraint(btScalar timeStep)
+void btSliderConstraint::getInfo1(btConstraintInfo1* info)
{
- m_timeStep = timeStep;
- if(m_useLinearReferenceFrameA)
+ if (m_useSolveConstraintObsolete)
{
- solveConstraintInt(m_rbA, m_rbB);
+ info->m_numConstraintRows = 0;
+ info->nub = 0;
}
else
{
- solveConstraintInt(m_rbB, m_rbA);
+ info->m_numConstraintRows = 4; // Fixed 2 linear + 2 angular
+ info->nub = 2;
+ //prepare constraint
+ calculateTransforms();
+ testLinLimits();
+ if(getSolveLinLimit() || getPoweredLinMotor())
+ {
+ info->m_numConstraintRows++; // limit 3rd linear as well
+ info->nub--;
+ }
+ testAngLimits();
+ if(getSolveAngLimit() || getPoweredAngMotor())
+ {
+ info->m_numConstraintRows++; // limit 3rd angular as well
+ info->nub--;
+ }
+ }
+} // btSliderConstraint::getInfo1()
+
+//-----------------------------------------------------------------------------
+
+void btSliderConstraint::getInfo2(btConstraintInfo2* info)
+{
+ btAssert(!m_useSolveConstraintObsolete);
+ int i, s = info->rowskip;
+ const btTransform& trA = getCalculatedTransformA();
+ const btTransform& trB = getCalculatedTransformB();
+ btScalar signFact = m_useLinearReferenceFrameA ? btScalar(1.0f) : btScalar(-1.0f);
+ // make rotations around Y and Z equal
+ // the slider axis should be the only unconstrained
+ // rotational axis, the angular velocity of the two bodies perpendicular to
+ // the slider axis should be equal. thus the constraint equations are
+ // p*w1 - p*w2 = 0
+ // q*w1 - q*w2 = 0
+ // where p and q are unit vectors normal to the slider axis, and w1 and w2
+ // are the angular velocity vectors of the two bodies.
+ // get slider axis (X)
+ btVector3 ax1 = trA.getBasis().getColumn(0);
+ // get 2 orthos to slider axis (Y, Z)
+ btVector3 p = trA.getBasis().getColumn(1);
+ btVector3 q = trA.getBasis().getColumn(2);
+ // set the two slider rows
+ info->m_J1angularAxis[0] = p[0];
+ info->m_J1angularAxis[1] = p[1];
+ info->m_J1angularAxis[2] = p[2];
+ info->m_J1angularAxis[s+0] = q[0];
+ info->m_J1angularAxis[s+1] = q[1];
+ info->m_J1angularAxis[s+2] = q[2];
+
+ info->m_J2angularAxis[0] = -p[0];
+ info->m_J2angularAxis[1] = -p[1];
+ info->m_J2angularAxis[2] = -p[2];
+ info->m_J2angularAxis[s+0] = -q[0];
+ info->m_J2angularAxis[s+1] = -q[1];
+ info->m_J2angularAxis[s+2] = -q[2];
+ // compute the right hand side of the constraint equation. set relative
+ // body velocities along p and q to bring the slider back into alignment.
+ // if ax1,ax2 are the unit length slider axes as computed from body1 and
+ // body2, we need to rotate both bodies along the axis u = (ax1 x ax2).
+ // if "theta" is the angle between ax1 and ax2, we need an angular velocity
+ // along u to cover angle erp*theta in one step :
+ // |angular_velocity| = angle/time = erp*theta / stepsize
+ // = (erp*fps) * theta
+ // angular_velocity = |angular_velocity| * (ax1 x ax2) / |ax1 x ax2|
+ // = (erp*fps) * theta * (ax1 x ax2) / sin(theta)
+ // ...as ax1 and ax2 are unit length. if theta is smallish,
+ // theta ~= sin(theta), so
+ // angular_velocity = (erp*fps) * (ax1 x ax2)
+ // ax1 x ax2 is in the plane space of ax1, so we project the angular
+ // velocity to p and q to find the right hand side.
+ btScalar k = info->fps * info->erp * getSoftnessOrthoAng();
+ btVector3 ax2 = trB.getBasis().getColumn(0);
+ btVector3 u = ax1.cross(ax2);
+ info->m_constraintError[0] = k * u.dot(p);
+ info->m_constraintError[s] = k * u.dot(q);
+ // pull out pos and R for both bodies. also get the connection
+ // vector c = pos2-pos1.
+ // next two rows. we want: vel2 = vel1 + w1 x c ... but this would
+ // result in three equations, so we project along the planespace vectors
+ // so that sliding along the slider axis is disregarded. for symmetry we
+ // also consider rotation around center of mass of two bodies (factA and factB).
+ btTransform bodyA_trans = m_rbA.getCenterOfMassTransform();
+ btTransform bodyB_trans = m_rbB.getCenterOfMassTransform();
+ int s2 = 2 * s, s3 = 3 * s;
+ btVector3 c;
+ btScalar miA = m_rbA.getInvMass();
+ btScalar miB = m_rbB.getInvMass();
+ btScalar miS = miA + miB;
+ btScalar factA, factB;
+ if(miS > btScalar(0.f))
+ {
+ factA = miB / miS;
+ }
+ else
+ {
+ factA = btScalar(0.5f);
+ }
+ if(factA > 0.99f) factA = 0.99f;
+ if(factA < 0.01f) factA = 0.01f;
+ factB = btScalar(1.0f) - factA;
+ c = bodyB_trans.getOrigin() - bodyA_trans.getOrigin();
+ btVector3 tmp = c.cross(p);
+ for (i=0; i<3; i++) info->m_J1angularAxis[s2+i] = factA*tmp[i];
+ for (i=0; i<3; i++) info->m_J2angularAxis[s2+i] = factB*tmp[i];
+ tmp = c.cross(q);
+ for (i=0; i<3; i++) info->m_J1angularAxis[s3+i] = factA*tmp[i];
+ for (i=0; i<3; i++) info->m_J2angularAxis[s3+i] = factB*tmp[i];
+
+ for (i=0; i<3; i++) info->m_J1linearAxis[s2+i] = p[i];
+ for (i=0; i<3; i++) info->m_J1linearAxis[s3+i] = q[i];
+ // compute two elements of right hand side. we want to align the offset
+ // point (in body 2's frame) with the center of body 1.
+ btVector3 ofs; // offset point in global coordinates
+ ofs = trB.getOrigin() - trA.getOrigin();
+ k = info->fps * info->erp * getSoftnessOrthoLin();
+ info->m_constraintError[s2] = k * p.dot(ofs);
+ info->m_constraintError[s3] = k * q.dot(ofs);
+ int nrow = 3; // last filled row
+ int srow;
+ // check linear limits linear
+ btScalar limit_err = btScalar(0.0);
+ int limit = 0;
+ if(getSolveLinLimit())
+ {
+ limit_err = getLinDepth() * signFact;
+ limit = (limit_err > btScalar(0.0)) ? 2 : 1;
+ }
+ int powered = 0;
+ if(getPoweredLinMotor())
+ {
+ powered = 1;
+ }
+ // if the slider has joint limits or motor, add in the extra row
+ if (limit || powered)
+ {
+ nrow++;
+ srow = nrow * info->rowskip;
+ info->m_J1linearAxis[srow+0] = ax1[0];
+ info->m_J1linearAxis[srow+1] = ax1[1];
+ info->m_J1linearAxis[srow+2] = ax1[2];
+ // linear torque decoupling step:
+ //
+ // we have to be careful that the linear constraint forces (+/- ax1) applied to the two bodies
+ // do not create a torque couple. in other words, the points that the
+ // constraint force is applied at must lie along the same ax1 axis.
+ // a torque couple will result in limited slider-jointed free
+ // bodies from gaining angular momentum.
+ // the solution used here is to apply the constraint forces at the center of mass of the two bodies
+ btVector3 ltd; // Linear Torque Decoupling vector (a torque)
+// c = btScalar(0.5) * c;
+ ltd = c.cross(ax1);
+ info->m_J1angularAxis[srow+0] = factA*ltd[0];
+ info->m_J1angularAxis[srow+1] = factA*ltd[1];
+ info->m_J1angularAxis[srow+2] = factA*ltd[2];
+ info->m_J2angularAxis[srow+0] = factB*ltd[0];
+ info->m_J2angularAxis[srow+1] = factB*ltd[1];
+ info->m_J2angularAxis[srow+2] = factB*ltd[2];
+ // right-hand part
+ btScalar lostop = getLowerLinLimit();
+ btScalar histop = getUpperLinLimit();
+ if(limit && (lostop == histop))
+ { // the joint motor is ineffective
+ powered = 0;
+ }
+ info->m_constraintError[srow] = 0.;
+ info->m_lowerLimit[srow] = 0.;
+ info->m_upperLimit[srow] = 0.;
+ if(powered)
+ {
+ info->cfm[nrow] = btScalar(0.0);
+ btScalar tag_vel = getTargetLinMotorVelocity();
+ btScalar mot_fact = getMotorFactor(m_linPos, m_lowerLinLimit, m_upperLinLimit, tag_vel, info->fps * info->erp);
+// info->m_constraintError[srow] += mot_fact * getTargetLinMotorVelocity();
+ info->m_constraintError[srow] -= signFact * mot_fact * getTargetLinMotorVelocity();
+ info->m_lowerLimit[srow] += -getMaxLinMotorForce() * info->fps;
+ info->m_upperLimit[srow] += getMaxLinMotorForce() * info->fps;
+ }
+ if(limit)
+ {
+ k = info->fps * info->erp;
+ info->m_constraintError[srow] += k * limit_err;
+ info->cfm[srow] = btScalar(0.0); // stop_cfm;
+ if(lostop == histop)
+ { // limited low and high simultaneously
+ info->m_lowerLimit[srow] = -SIMD_INFINITY;
+ info->m_upperLimit[srow] = SIMD_INFINITY;
+ }
+ else if(limit == 1)
+ { // low limit
+ info->m_lowerLimit[srow] = -SIMD_INFINITY;
+ info->m_upperLimit[srow] = 0;
+ }
+ else
+ { // high limit
+ info->m_lowerLimit[srow] = 0;
+ info->m_upperLimit[srow] = SIMD_INFINITY;
+ }
+ // bounce (we'll use slider parameter abs(1.0 - m_dampingLimLin) for that)
+ btScalar bounce = btFabs(btScalar(1.0) - getDampingLimLin());
+ if(bounce > btScalar(0.0))
+ {
+ btScalar vel = m_rbA.getLinearVelocity().dot(ax1);
+ vel -= m_rbB.getLinearVelocity().dot(ax1);
+ vel *= signFact;
+ // only apply bounce if the velocity is incoming, and if the
+ // resulting c[] exceeds what we already have.
+ if(limit == 1)
+ { // low limit
+ if(vel < 0)
+ {
+ btScalar newc = -bounce * vel;
+ if (newc > info->m_constraintError[srow])
+ {
+ info->m_constraintError[srow] = newc;
+ }
+ }
+ }
+ else
+ { // high limit - all those computations are reversed
+ if(vel > 0)
+ {
+ btScalar newc = -bounce * vel;
+ if(newc < info->m_constraintError[srow])
+ {
+ info->m_constraintError[srow] = newc;
+ }
+ }
+ }
+ }
+ info->m_constraintError[srow] *= getSoftnessLimLin();
+ } // if(limit)
+ } // if linear limit
+ // check angular limits
+ limit_err = btScalar(0.0);
+ limit = 0;
+ if(getSolveAngLimit())
+ {
+ limit_err = getAngDepth();
+ limit = (limit_err > btScalar(0.0)) ? 1 : 2;
+ }
+ // if the slider has joint limits, add in the extra row
+ powered = 0;
+ if(getPoweredAngMotor())
+ {
+ powered = 1;
+ }
+ if(limit || powered)
+ {
+ nrow++;
+ srow = nrow * info->rowskip;
+ info->m_J1angularAxis[srow+0] = ax1[0];
+ info->m_J1angularAxis[srow+1] = ax1[1];
+ info->m_J1angularAxis[srow+2] = ax1[2];
+
+ info->m_J2angularAxis[srow+0] = -ax1[0];
+ info->m_J2angularAxis[srow+1] = -ax1[1];
+ info->m_J2angularAxis[srow+2] = -ax1[2];
+
+ btScalar lostop = getLowerAngLimit();
+ btScalar histop = getUpperAngLimit();
+ if(limit && (lostop == histop))
+ { // the joint motor is ineffective
+ powered = 0;
+ }
+ if(powered)
+ {
+ info->cfm[srow] = btScalar(0.0);
+ btScalar mot_fact = getMotorFactor(m_angPos, m_lowerAngLimit, m_upperAngLimit, getTargetAngMotorVelocity(), info->fps * info->erp);
+ info->m_constraintError[srow] = mot_fact * getTargetAngMotorVelocity();
+ info->m_lowerLimit[srow] = -getMaxAngMotorForce() * info->fps;
+ info->m_upperLimit[srow] = getMaxAngMotorForce() * info->fps;
+ }
+ if(limit)
+ {
+ k = info->fps * info->erp;
+ info->m_constraintError[srow] += k * limit_err;
+ info->cfm[srow] = btScalar(0.0); // stop_cfm;
+ if(lostop == histop)
+ {
+ // limited low and high simultaneously
+ info->m_lowerLimit[srow] = -SIMD_INFINITY;
+ info->m_upperLimit[srow] = SIMD_INFINITY;
+ }
+ else if(limit == 1)
+ { // low limit
+ info->m_lowerLimit[srow] = 0;
+ info->m_upperLimit[srow] = SIMD_INFINITY;
+ }
+ else
+ { // high limit
+ info->m_lowerLimit[srow] = -SIMD_INFINITY;
+ info->m_upperLimit[srow] = 0;
+ }
+ // bounce (we'll use slider parameter abs(1.0 - m_dampingLimAng) for that)
+ btScalar bounce = btFabs(btScalar(1.0) - getDampingLimAng());
+ if(bounce > btScalar(0.0))
+ {
+ btScalar vel = m_rbA.getAngularVelocity().dot(ax1);
+ vel -= m_rbB.getAngularVelocity().dot(ax1);
+ // only apply bounce if the velocity is incoming, and if the
+ // resulting c[] exceeds what we already have.
+ if(limit == 1)
+ { // low limit
+ if(vel < 0)
+ {
+ btScalar newc = -bounce * vel;
+ if(newc > info->m_constraintError[srow])
+ {
+ info->m_constraintError[srow] = newc;
+ }
+ }
+ }
+ else
+ { // high limit - all those computations are reversed
+ if(vel > 0)
+ {
+ btScalar newc = -bounce * vel;
+ if(newc < info->m_constraintError[srow])
+ {
+ info->m_constraintError[srow] = newc;
+ }
+ }
+ }
+ }
+ info->m_constraintError[srow] *= getSoftnessLimAng();
+ } // if(limit)
+ } // if angular limit or powered
+} // btSliderConstraint::getInfo2()
+
+//-----------------------------------------------------------------------------
+
+void btSliderConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep)
+{
+ if (m_useSolveConstraintObsolete)
+ {
+ m_timeStep = timeStep;
+ if(m_useLinearReferenceFrameA)
+ {
+ solveConstraintInt(m_rbA,bodyA, m_rbB,bodyB);
+ }
+ else
+ {
+ solveConstraintInt(m_rbB,bodyB, m_rbA,bodyA);
+ }
}
} // btSliderConstraint::solveConstraint()
//-----------------------------------------------------------------------------
-void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, btRigidBody& rbB)
+void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, btSolverBody& bodyA,btRigidBody& rbB, btSolverBody& bodyB)
{
int i;
// linear
- btVector3 velA = rbA.getVelocityInLocalPoint(m_relPosA);
- btVector3 velB = rbB.getVelocityInLocalPoint(m_relPosB);
+ btVector3 velA;
+ bodyA.getVelocityInLocalPointObsolete(m_relPosA,velA);
+ btVector3 velB;
+ bodyB.getVelocityInLocalPointObsolete(m_relPosB,velB);
btVector3 vel = velA - velB;
for(i = 0; i < 3; i++)
{
@@ -190,8 +543,18 @@ void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, btRigidBody& rbB)
// calcutate and apply impulse
btScalar normalImpulse = softness * (restitution * depth / m_timeStep - damping * rel_vel) * m_jacLinDiagABInv[i];
btVector3 impulse_vector = normal * normalImpulse;
- rbA.applyImpulse( impulse_vector, m_relPosA);
- rbB.applyImpulse(-impulse_vector, m_relPosB);
+
+ //rbA.applyImpulse( impulse_vector, m_relPosA);
+ //rbB.applyImpulse(-impulse_vector, m_relPosB);
+ {
+ btVector3 ftorqueAxis1 = m_relPosA.cross(normal);
+ btVector3 ftorqueAxis2 = m_relPosB.cross(normal);
+ bodyA.applyImpulse(normal*rbA.getInvMass(), rbA.getInvInertiaTensorWorld()*ftorqueAxis1,normalImpulse);
+ bodyB.applyImpulse(normal*rbB.getInvMass(), rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-normalImpulse);
+ }
+
+
+
if(m_poweredLinMotor && (!i))
{ // apply linear motor
if(m_accumulatedLinMotorImpulse < m_maxLinMotorForce)
@@ -217,8 +580,18 @@ void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, btRigidBody& rbB)
m_accumulatedLinMotorImpulse = new_acc;
// apply clamped impulse
impulse_vector = normal * normalImpulse;
- rbA.applyImpulse( impulse_vector, m_relPosA);
- rbB.applyImpulse(-impulse_vector, m_relPosB);
+ //rbA.applyImpulse( impulse_vector, m_relPosA);
+ //rbB.applyImpulse(-impulse_vector, m_relPosB);
+
+ {
+ btVector3 ftorqueAxis1 = m_relPosA.cross(normal);
+ btVector3 ftorqueAxis2 = m_relPosB.cross(normal);
+ bodyA.applyImpulse(normal*rbA.getInvMass(), rbA.getInvInertiaTensorWorld()*ftorqueAxis1,normalImpulse);
+ bodyB.applyImpulse(normal*rbB.getInvMass(), rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-normalImpulse);
+ }
+
+
+
}
}
}
@@ -227,8 +600,10 @@ void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, btRigidBody& rbB)
btVector3 axisA = m_calculatedTransformA.getBasis().getColumn(0);
btVector3 axisB = m_calculatedTransformB.getBasis().getColumn(0);
- const btVector3& angVelA = rbA.getAngularVelocity();
- const btVector3& angVelB = rbB.getAngularVelocity();
+ btVector3 angVelA;
+ bodyA.getAngularVelocity(angVelA);
+ btVector3 angVelB;
+ bodyB.getAngularVelocity(angVelB);
btVector3 angVelAroundAxisA = axisA * axisA.dot(angVelA);
btVector3 angVelAroundAxisB = axisB * axisB.dot(angVelB);
@@ -238,24 +613,38 @@ void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, btRigidBody& rbB)
btVector3 velrelOrthog = angAorthog-angBorthog;
//solve orthogonal angular velocity correction
btScalar len = velrelOrthog.length();
+ btScalar orthorImpulseMag = 0.f;
+
if (len > btScalar(0.00001))
{
btVector3 normal = velrelOrthog.normalized();
btScalar denom = rbA.computeAngularImpulseDenominator(normal) + rbB.computeAngularImpulseDenominator(normal);
- velrelOrthog *= (btScalar(1.)/denom) * m_dampingOrthoAng * m_softnessOrthoAng;
+ //velrelOrthog *= (btScalar(1.)/denom) * m_dampingOrthoAng * m_softnessOrthoAng;
+ orthorImpulseMag = (btScalar(1.)/denom) * m_dampingOrthoAng * m_softnessOrthoAng;
}
//solve angular positional correction
btVector3 angularError = axisA.cross(axisB) *(btScalar(1.)/m_timeStep);
+ btVector3 angularAxis = angularError;
+ btScalar angularImpulseMag = 0;
+
btScalar len2 = angularError.length();
if (len2>btScalar(0.00001))
{
btVector3 normal2 = angularError.normalized();
btScalar denom2 = rbA.computeAngularImpulseDenominator(normal2) + rbB.computeAngularImpulseDenominator(normal2);
- angularError *= (btScalar(1.)/denom2) * m_restitutionOrthoAng * m_softnessOrthoAng;
+ angularImpulseMag = (btScalar(1.)/denom2) * m_restitutionOrthoAng * m_softnessOrthoAng;
+ angularError *= angularImpulseMag;
}
// apply impulse
- rbA.applyTorqueImpulse(-velrelOrthog+angularError);
- rbB.applyTorqueImpulse(velrelOrthog-angularError);
+ //rbA.applyTorqueImpulse(-velrelOrthog+angularError);
+ //rbB.applyTorqueImpulse(velrelOrthog-angularError);
+
+ bodyA.applyImpulse(btVector3(0,0,0), rbA.getInvInertiaTensorWorld()*velrelOrthog,-orthorImpulseMag);
+ bodyB.applyImpulse(btVector3(0,0,0), rbB.getInvInertiaTensorWorld()*velrelOrthog,orthorImpulseMag);
+ bodyA.applyImpulse(btVector3(0,0,0), rbA.getInvInertiaTensorWorld()*angularAxis,angularImpulseMag);
+ bodyB.applyImpulse(btVector3(0,0,0), rbB.getInvInertiaTensorWorld()*angularAxis,-angularImpulseMag);
+
+
btScalar impulseMag;
//solve angular limits
if(m_solveAngLim)
@@ -269,8 +658,14 @@ void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, btRigidBody& rbB)
impulseMag *= m_kAngle * m_softnessDirAng;
}
btVector3 impulse = axisA * impulseMag;
- rbA.applyTorqueImpulse(impulse);
- rbB.applyTorqueImpulse(-impulse);
+ //rbA.applyTorqueImpulse(impulse);
+ //rbB.applyTorqueImpulse(-impulse);
+
+ bodyA.applyImpulse(btVector3(0,0,0), rbA.getInvInertiaTensorWorld()*axisA,impulseMag);
+ bodyB.applyImpulse(btVector3(0,0,0), rbB.getInvInertiaTensorWorld()*axisA,-impulseMag);
+
+
+
//apply angular motor
if(m_poweredAngMotor)
{
@@ -301,8 +696,11 @@ void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, btRigidBody& rbB)
m_accumulatedAngMotorImpulse = new_acc;
// apply clamped impulse
btVector3 motorImp = angImpulse * axisA;
- m_rbA.applyTorqueImpulse(motorImp);
- m_rbB.applyTorqueImpulse(-motorImp);
+ //rbA.applyTorqueImpulse(motorImp);
+ //rbB.applyTorqueImpulse(-motorImp);
+
+ bodyA.applyImpulse(btVector3(0,0,0), rbA.getInvInertiaTensorWorld()*axisA,angImpulse);
+ bodyB.applyImpulse(btVector3(0,0,0), rbB.getInvInertiaTensorWorld()*axisA,-angImpulse);
}
}
} // btSliderConstraint::solveConstraint()
@@ -312,7 +710,7 @@ void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, btRigidBody& rbB)
//-----------------------------------------------------------------------------
void btSliderConstraint::calculateTransforms(void){
- if(m_useLinearReferenceFrameA)
+ if(m_useLinearReferenceFrameA || (!m_useSolveConstraintObsolete))
{
m_calculatedTransformA = m_rbA.getCenterOfMassTransform() * m_frameInA;
m_calculatedTransformB = m_rbB.getCenterOfMassTransform() * m_frameInB;
@@ -325,7 +723,14 @@ void btSliderConstraint::calculateTransforms(void){
m_realPivotAInW = m_calculatedTransformA.getOrigin();
m_realPivotBInW = m_calculatedTransformB.getOrigin();
m_sliderAxis = m_calculatedTransformA.getBasis().getColumn(0); // along X
- m_delta = m_realPivotBInW - m_realPivotAInW;
+ if(m_useLinearReferenceFrameA || m_useSolveConstraintObsolete)
+ {
+ m_delta = m_realPivotBInW - m_realPivotAInW;
+ }
+ else
+ {
+ m_delta = m_realPivotAInW - m_realPivotBInW;
+ }
m_projPivotInW = m_realPivotAInW + m_sliderAxis.dot(m_delta) * m_sliderAxis;
btVector3 normalWorld;
int i;
@@ -367,7 +772,6 @@ void btSliderConstraint::testLinLimits(void)
} // btSliderConstraint::testLinLimits()
//-----------------------------------------------------------------------------
-
void btSliderConstraint::testAngLimits(void)
{
@@ -379,6 +783,7 @@ void btSliderConstraint::testAngLimits(void)
const btVector3 axisA1 = m_calculatedTransformA.getBasis().getColumn(2);
const btVector3 axisB0 = m_calculatedTransformB.getBasis().getColumn(1);
btScalar rot = btAtan2Fast(axisB0.dot(axisA1), axisB0.dot(axisA0));
+ m_angPos = rot;
if(rot < m_lowerAngLimit)
{
m_angDepth = rot - m_lowerAngLimit;
@@ -391,12 +796,9 @@ void btSliderConstraint::testAngLimits(void)
}
}
} // btSliderConstraint::testAngLimits()
-
//-----------------------------------------------------------------------------
-
-
btVector3 btSliderConstraint::getAncorInA(void)
{
btVector3 ancorInA;
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h
index 580dfa1178d..70fbce5d9b2 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h
@@ -46,6 +46,8 @@ class btRigidBody;
class btSliderConstraint : public btTypedConstraint
{
protected:
+ ///for backwards compatibility during the transition to 'getInfo/getInfo2'
+ bool m_useSolveConstraintObsolete;
btTransform m_frameInA;
btTransform m_frameInB;
// use frameA fo define limits, if true
@@ -104,6 +106,7 @@ protected:
btVector3 m_relPosB;
btScalar m_linPos;
+ btScalar m_angPos;
btScalar m_angDepth;
btScalar m_kAngle;
@@ -126,7 +129,13 @@ public:
btSliderConstraint();
// overrides
virtual void buildJacobian();
- virtual void solveConstraint(btScalar timeStep);
+ virtual void getInfo1 (btConstraintInfo1* info);
+
+ virtual void getInfo2 (btConstraintInfo2* info);
+
+ virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep);
+
+
// access
const btRigidBody& getRigidBodyA() const { return m_rbA; }
const btRigidBody& getRigidBodyB() const { return m_rbB; }
@@ -194,6 +203,7 @@ public:
void setMaxAngMotorForce(btScalar maxAngMotorForce) { m_maxAngMotorForce = maxAngMotorForce; }
btScalar getMaxAngMotorForce() { return m_maxAngMotorForce; }
btScalar getLinearPos() { return m_linPos; }
+
// access for ODE solver
bool getSolveLinLimit() { return m_solveLinLim; }
@@ -202,10 +212,11 @@ public:
btScalar getAngDepth() { return m_angDepth; }
// internal
void buildJacobianInt(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB);
- void solveConstraintInt(btRigidBody& rbA, btRigidBody& rbB);
+ void solveConstraintInt(btRigidBody& rbA, btSolverBody& bodyA,btRigidBody& rbB, btSolverBody& bodyB);
// shared code used by ODE solver
void calculateTransforms(void);
void testLinLimits(void);
+ void testLinLimits2(btConstraintInfo2* info);
void testAngLimits(void);
// access for PE Solver
btVector3 getAncorInA(void);
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
index b3f0c9d7444..6b728959162 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
@@ -23,86 +23,152 @@ class btRigidBody;
#include "LinearMath/btAlignedAllocator.h"
#include "LinearMath/btTransformUtil.h"
+///Until we get other contributions, only use SIMD on Windows, when using Visual Studio 2008 or later, and not double precision
+#ifdef BT_USE_SSE
+#define USE_SIMD 1
+#endif //
-///btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance.
+
+#ifdef USE_SIMD
+
+struct btSimdScalar
+{
+ SIMD_FORCE_INLINE btSimdScalar()
+ {
+
+ }
+
+ SIMD_FORCE_INLINE btSimdScalar(float fl)
+ :m_vec128 (_mm_set1_ps(fl))
+ {
+ }
+
+ SIMD_FORCE_INLINE btSimdScalar(__m128 v128)
+ :m_vec128(v128)
+ {
+ }
+ union
+ {
+ __m128 m_vec128;
+ float m_floats[4];
+ int m_ints[4];
+ btScalar m_unusedPadding;
+ };
+ SIMD_FORCE_INLINE __m128 get128()
+ {
+ return m_vec128;
+ }
+
+ SIMD_FORCE_INLINE const __m128 get128() const
+ {
+ return m_vec128;
+ }
+
+ SIMD_FORCE_INLINE void set128(__m128 v128)
+ {
+ m_vec128 = v128;
+ }
+
+ SIMD_FORCE_INLINE operator __m128()
+ {
+ return m_vec128;
+ }
+ SIMD_FORCE_INLINE operator const __m128() const
+ {
+ return m_vec128;
+ }
+
+ SIMD_FORCE_INLINE operator float() const
+ {
+ return m_floats[0];
+ }
+
+};
+
+///@brief Return the elementwise product of two btSimdScalar
+SIMD_FORCE_INLINE btSimdScalar
+operator*(const btSimdScalar& v1, const btSimdScalar& v2)
+{
+ return btSimdScalar(_mm_mul_ps(v1.get128(),v2.get128()));
+}
+
+///@brief Return the elementwise product of two btSimdScalar
+SIMD_FORCE_INLINE btSimdScalar
+operator+(const btSimdScalar& v1, const btSimdScalar& v2)
+{
+ return btSimdScalar(_mm_add_ps(v1.get128(),v2.get128()));
+}
+
+
+#else
+#define btSimdScalar btScalar
+#endif
+
+///The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance.
ATTRIBUTE_ALIGNED16 (struct) btSolverBody
{
BT_DECLARE_ALIGNED_ALLOCATOR();
-
- btVector3 m_angularVelocity;
- float m_angularFactor;
- float m_invMass;
- float m_friction;
+ btVector3 m_deltaLinearVelocity;
+ btVector3 m_deltaAngularVelocity;
+ btVector3 m_angularFactor;
+ btVector3 m_invMass;
+ btScalar m_friction;
btRigidBody* m_originalBody;
- btVector3 m_linearVelocity;
- btVector3 m_centerOfMassPosition;
-
btVector3 m_pushVelocity;
- btVector3 m_turnVelocity;
-
+ //btVector3 m_turnVelocity;
+
- SIMD_FORCE_INLINE void getVelocityInLocalPoint(const btVector3& rel_pos, btVector3& velocity ) const
+ SIMD_FORCE_INLINE void getVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity ) const
{
- velocity = m_linearVelocity + m_angularVelocity.cross(rel_pos);
+ if (m_originalBody)
+ velocity = m_originalBody->getLinearVelocity()+m_deltaLinearVelocity + (m_originalBody->getAngularVelocity()+m_deltaAngularVelocity).cross(rel_pos);
+ else
+ velocity.setValue(0,0,0);
}
- //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
- SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude)
+ SIMD_FORCE_INLINE void getAngularVelocity(btVector3& angVel) const
{
- if (m_invMass)
- {
- m_linearVelocity += linearComponent*impulseMagnitude;
- m_angularVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
- }
+ if (m_originalBody)
+ angVel = m_originalBody->getAngularVelocity()+m_deltaAngularVelocity;
+ else
+ angVel.setValue(0,0,0);
}
-
- SIMD_FORCE_INLINE void internalApplyPushImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude)
+
+
+ //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
+ SIMD_FORCE_INLINE void applyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,const btScalar impulseMagnitude)
{
- if (m_invMass)
+ //if (m_invMass)
{
- m_pushVelocity += linearComponent*impulseMagnitude;
- m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
+ m_deltaLinearVelocity += linearComponent*impulseMagnitude;
+ m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
}
}
+/*
+
void writebackVelocity()
{
if (m_invMass)
{
- m_originalBody->setLinearVelocity(m_linearVelocity);
- m_originalBody->setAngularVelocity(m_angularVelocity);
+ m_originalBody->setLinearVelocity(m_originalBody->getLinearVelocity()+ m_deltaLinearVelocity);
+ m_originalBody->setAngularVelocity(m_originalBody->getAngularVelocity()+m_deltaAngularVelocity);
//m_originalBody->setCompanionId(-1);
}
}
-
+ */
- void writebackVelocity(btScalar timeStep)
+ void writebackVelocity(btScalar timeStep=0)
{
- if (m_invMass)
+ if (m_originalBody)
{
- m_originalBody->setLinearVelocity(m_linearVelocity);
- m_originalBody->setAngularVelocity(m_angularVelocity);
-
- //correct the position/orientation based on push/turn recovery
- btTransform newTransform;
- btTransformUtil::integrateTransform(m_originalBody->getWorldTransform(),m_pushVelocity,m_turnVelocity,timeStep,newTransform);
- m_originalBody->setWorldTransform(newTransform);
-
+ m_originalBody->setLinearVelocity(m_originalBody->getLinearVelocity()+m_deltaLinearVelocity);
+ m_originalBody->setAngularVelocity(m_originalBody->getAngularVelocity()+m_deltaAngularVelocity);
//m_originalBody->setCompanionId(-1);
}
}
-
- void readVelocity()
- {
- if (m_invMass)
- {
- m_linearVelocity = m_originalBody->getLinearVelocity();
- m_angularVelocity = m_originalBody->getAngularVelocity();
- }
- }
-
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h
index 2c71360c5b9..867d62a301d 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h
@@ -19,40 +19,64 @@ subject to the following restrictions:
class btRigidBody;
#include "LinearMath/btVector3.h"
#include "LinearMath/btMatrix3x3.h"
+#include "btJacobianEntry.h"
//#define NO_FRICTION_TANGENTIALS 1
+#include "btSolverBody.h"
+
///1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and friction constraints.
ATTRIBUTE_ALIGNED16 (struct) btSolverConstraint
{
BT_DECLARE_ALIGNED_ALLOCATOR();
- btVector3 m_relpos1CrossNormal;
- btVector3 m_contactNormal;
-
- btVector3 m_relpos2CrossNormal;
- btVector3 m_angularComponentA;
+ btVector3 m_relpos1CrossNormal;
+ btVector3 m_contactNormal;
- btVector3 m_angularComponentB;
+ btVector3 m_relpos2CrossNormal;
+ //btVector3 m_contactNormal2;//usually m_contactNormal2 == -m_contactNormal
- mutable btScalar m_appliedPushImpulse;
+ btVector3 m_angularComponentA;
+ btVector3 m_angularComponentB;
+
+ mutable btSimdScalar m_appliedPushImpulse;
+ mutable btSimdScalar m_appliedImpulse;
- mutable btScalar m_appliedImpulse;
- int m_solverBodyIdA;
- int m_solverBodyIdB;
btScalar m_friction;
- btScalar m_restitution;
btScalar m_jacDiagABInv;
- btScalar m_penetration;
-
+ union
+ {
+ int m_numConsecutiveRowsPerKernel;
+ btScalar m_unusedPadding0;
+ };
+ union
+ {
+ int m_frictionIndex;
+ btScalar m_unusedPadding1;
+ };
+ union
+ {
+ int m_solverBodyIdA;
+ btScalar m_unusedPadding2;
+ };
+ union
+ {
+ int m_solverBodyIdB;
+ btScalar m_unusedPadding3;
+ };
- int m_constraintType;
- int m_frictionIndex;
- void* m_originalContactPoint;
- int m_unusedPadding[1];
+ union
+ {
+ void* m_originalContactPoint;
+ btScalar m_unusedPadding4;
+ };
+ btScalar m_rhs;
+ btScalar m_cfm;
+ btScalar m_lowerLimit;
+ btScalar m_upperLimit;
enum btSolverConstraintType
{
@@ -61,9 +85,7 @@ ATTRIBUTE_ALIGNED16 (struct) btSolverConstraint
};
};
-
-
-
+typedef btAlignedObjectArray<btSolverConstraint> btConstraintArray;
#endif //BT_SOLVER_CONSTRAINT_H
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
index 6e8b552dbbc..3fa98ee4c88 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
@@ -19,13 +19,16 @@ subject to the following restrictions:
static btRigidBody s_fixed(0, 0,0);
+#define DEFAULT_DEBUGDRAW_SIZE btScalar(0.3f)
+
btTypedConstraint::btTypedConstraint(btTypedConstraintType type)
:m_userConstraintType(-1),
m_userConstraintId(-1),
m_constraintType (type),
m_rbA(s_fixed),
m_rbB(s_fixed),
-m_appliedImpulse(btScalar(0.))
+m_appliedImpulse(btScalar(0.)),
+m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
{
s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
}
@@ -35,7 +38,8 @@ m_userConstraintId(-1),
m_constraintType (type),
m_rbA(rbA),
m_rbB(s_fixed),
-m_appliedImpulse(btScalar(0.))
+m_appliedImpulse(btScalar(0.)),
+m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
{
s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
@@ -48,9 +52,63 @@ m_userConstraintId(-1),
m_constraintType (type),
m_rbA(rbA),
m_rbB(rbB),
-m_appliedImpulse(btScalar(0.))
+m_appliedImpulse(btScalar(0.)),
+m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
{
s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
}
+
+//-----------------------------------------------------------------------------
+
+btScalar btTypedConstraint::getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact)
+{
+ if(lowLim > uppLim)
+ {
+ return btScalar(1.0f);
+ }
+ else if(lowLim == uppLim)
+ {
+ return btScalar(0.0f);
+ }
+ btScalar lim_fact = btScalar(1.0f);
+ btScalar delta_max = vel / timeFact;
+ if(delta_max < btScalar(0.0f))
+ {
+ if((pos >= lowLim) && (pos < (lowLim - delta_max)))
+ {
+ lim_fact = (lowLim - pos) / delta_max;
+ }
+ else if(pos < lowLim)
+ {
+ lim_fact = btScalar(0.0f);
+ }
+ else
+ {
+ lim_fact = btScalar(1.0f);
+ }
+ }
+ else if(delta_max > btScalar(0.0f))
+ {
+ if((pos <= uppLim) && (pos > (uppLim - delta_max)))
+ {
+ lim_fact = (uppLim - pos) / delta_max;
+ }
+ else if(pos > uppLim)
+ {
+ lim_fact = btScalar(0.0f);
+ }
+ else
+ {
+ lim_fact = btScalar(1.0f);
+ }
+ }
+ else
+ {
+ lim_fact = btScalar(0.0f);
+ }
+ return lim_fact;
+} // btTypedConstraint::getMotorFactor()
+
+
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
index c50ec6ec579..14cbe831b40 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
@@ -18,6 +18,11 @@ subject to the following restrictions:
class btRigidBody;
#include "LinearMath/btScalar.h"
+#include "btSolverConstraint.h"
+struct btSolverBody;
+
+
+
enum btTypedConstraintType
{
@@ -25,7 +30,6 @@ enum btTypedConstraintType
HINGE_CONSTRAINT_TYPE,
CONETWIST_CONSTRAINT_TYPE,
D6_CONSTRAINT_TYPE,
- VEHICLE_CONSTRAINT_TYPE,
SLIDER_CONSTRAINT_TYPE
};
@@ -48,6 +52,7 @@ protected:
btRigidBody& m_rbA;
btRigidBody& m_rbB;
btScalar m_appliedImpulse;
+ btScalar m_dbgDrawSize;
public:
@@ -55,13 +60,55 @@ public:
btTypedConstraint(btTypedConstraintType type);
virtual ~btTypedConstraint() {};
btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA);
-
btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB);
+ struct btConstraintInfo1 {
+ int m_numConstraintRows,nub;
+ };
+
+ struct btConstraintInfo2 {
+ // integrator parameters: frames per second (1/stepsize), default error
+ // reduction parameter (0..1).
+ btScalar fps,erp;
+
+ // for the first and second body, pointers to two (linear and angular)
+ // n*3 jacobian sub matrices, stored by rows. these matrices will have
+ // been initialized to 0 on entry. if the second body is zero then the
+ // J2xx pointers may be 0.
+ btScalar *m_J1linearAxis,*m_J1angularAxis,*m_J2linearAxis,*m_J2angularAxis;
+
+ // elements to jump from one row to the next in J's
+ int rowskip;
+
+ // right hand sides of the equation J*v = c + cfm * lambda. cfm is the
+ // "constraint force mixing" vector. c is set to zero on entry, cfm is
+ // set to a constant value (typically very small or zero) value on entry.
+ btScalar *m_constraintError,*cfm;
+
+ // lo and hi limits for variables (set to -/+ infinity on entry).
+ btScalar *m_lowerLimit,*m_upperLimit;
+
+ // findex vector for variables. see the LCP solver interface for a
+ // description of what this does. this is set to -1 on entry.
+ // note that the returned indexes are relative to the first index of
+ // the constraint.
+ int *findex;
+ };
+
+
virtual void buildJacobian() = 0;
- virtual void solveConstraint(btScalar timeStep) = 0;
+ virtual void setupSolverConstraint(btConstraintArray& ca, int solverBodyA,int solverBodyB, btScalar timeStep)
+ {
+ }
+ virtual void getInfo1 (btConstraintInfo1* info)=0;
+
+ virtual void getInfo2 (btConstraintInfo2* info)=0;
+ virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) = 0;
+
+ btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact);
+
const btRigidBody& getRigidBodyA() const
{
return m_rbA;
@@ -94,7 +141,7 @@ public:
{
m_userConstraintId = uid;
}
-
+
int getUserConstraintId() const
{
return m_userConstraintId;
@@ -114,7 +161,16 @@ public:
{
return m_constraintType;
}
-
+
+ void setDbgDrawSize(btScalar dbgDrawSize)
+ {
+ m_dbgDrawSize = dbgDrawSize;
+ }
+ btScalar getDbgDrawSize()
+ {
+ return m_dbgDrawSize;
+ }
+
};
#endif //TYPED_CONSTRAINT_H
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp
index c2fd71d67fe..47addbac45b 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/Bullet-C-API.cpp
@@ -38,7 +38,7 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
-#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h"
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
@@ -110,16 +110,16 @@ void plDeleteDynamicsWorld(plDynamicsWorldHandle world)
void plStepSimulation(plDynamicsWorldHandle world, plReal timeStep)
{
btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);
- assert(dynamicsWorld);
+ btAssert(dynamicsWorld);
dynamicsWorld->stepSimulation(timeStep);
}
void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object)
{
btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);
- assert(dynamicsWorld);
+ btAssert(dynamicsWorld);
btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
- assert(body);
+ btAssert(body);
dynamicsWorld->addRigidBody(body);
}
@@ -127,9 +127,9 @@ void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object)
void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object)
{
btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);
- assert(dynamicsWorld);
+ btAssert(dynamicsWorld);
btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
- assert(body);
+ btAssert(body);
dynamicsWorld->removeRigidBody(body);
}
@@ -142,7 +142,7 @@ plRigidBodyHandle plCreateRigidBody( void* user_data, float mass, plCollisionSh
trans.setIdentity();
btVector3 localInertia(0,0,0);
btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape);
- assert(shape);
+ btAssert(shape);
if (mass)
{
shape->calculateLocalInertia(mass,localInertia);
@@ -158,7 +158,7 @@ plRigidBodyHandle plCreateRigidBody( void* user_data, float mass, plCollisionSh
void plDeleteRigidBody(plRigidBodyHandle cbody)
{
btRigidBody* body = reinterpret_cast< btRigidBody* >(cbody);
- assert(body);
+ btAssert(body);
btAlignedFree( body);
}
@@ -255,20 +255,20 @@ void plAddVertex(plCollisionShapeHandle cshape, plReal x,plReal y,plReal z)
(void)colShape;
btAssert(colShape->getShapeType()==CONVEX_HULL_SHAPE_PROXYTYPE);
btConvexHullShape* convexHullShape = reinterpret_cast<btConvexHullShape*>( cshape);
- convexHullShape->addPoint(btPoint3(x,y,z));
+ convexHullShape->addPoint(btVector3(x,y,z));
}
void plDeleteShape(plCollisionShapeHandle cshape)
{
btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape);
- assert(shape);
+ btAssert(shape);
btAlignedFree(shape);
}
void plSetScaling(plCollisionShapeHandle cshape, plVector3 cscaling)
{
btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape);
- assert(shape);
+ btAssert(shape);
btVector3 scaling(cscaling[0],cscaling[1],cscaling[2]);
shape->setLocalScaling(scaling);
}
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btActionInterface.h b/extern/bullet2/src/BulletDynamics/Dynamics/btActionInterface.h
new file mode 100644
index 00000000000..8348795ef70
--- /dev/null
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btActionInterface.h
@@ -0,0 +1,39 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+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_ACTION_INTERFACE_H
+#define _BT_ACTION_INTERFACE_H
+
+class btIDebugDraw;
+class btCollisionWorld;
+
+#include "LinearMath/btScalar.h"
+
+///Basic interface to allow actions such as vehicles and characters to be updated inside a btDynamicsWorld
+class btActionInterface
+{
+ public:
+
+ virtual ~btActionInterface()
+ {
+ }
+
+ virtual void updateAction( btCollisionWorld* collisionWorld, btScalar deltaTimeStep)=0;
+
+ virtual void debugDraw(btIDebugDraw* debugDrawer) = 0;
+
+};
+
+#endif //_BT_ACTION_INTERFACE_H \ No newline at end of file
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp
index 19443adc723..fa0d63d74a1 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp
@@ -90,8 +90,7 @@ void btContinuousDynamicsWorld::internalSingleStepSimulation( btScalar timeStep)
integrateTransforms(timeStep * toi);
///update vehicle simulation
- updateVehicles(timeStep);
-
+ updateActions(timeStep);
updateActivationState( timeStep );
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
index 745694e2f70..ea2e0ad2a2b 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
@@ -29,6 +29,11 @@ subject to the following restrictions:
#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btSliderConstraint.h"
//for debug rendering
#include "BulletCollision/CollisionShapes/btBoxShape.h"
@@ -46,12 +51,7 @@ subject to the following restrictions:
#include "LinearMath/btIDebugDraw.h"
-
-//vehicle
-#include "BulletDynamics/Vehicle/btRaycastVehicle.h"
-#include "BulletDynamics/Vehicle/btVehicleRaycaster.h"
-#include "BulletDynamics/Vehicle/btWheelInfo.h"
-#include "LinearMath/btIDebugDraw.h"
+#include "BulletDynamics/Dynamics/btActionInterface.h"
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btMotionState.h"
@@ -110,7 +110,6 @@ void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep)
btRigidBody* body = btRigidBody::upcast(colObj);
if (body)
{
- btTransform predictedTrans;
if (body->getActivationState() != ISLAND_SLEEPING)
{
if (body->isKinematicObject())
@@ -125,6 +124,7 @@ void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep)
void btDiscreteDynamicsWorld::debugDrawWorld()
{
+ BT_PROFILE("debugDrawWorld");
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
{
@@ -144,13 +144,30 @@ void btDiscreteDynamicsWorld::debugDrawWorld()
}
}
}
+ bool drawConstraints = false;
+ if (getDebugDrawer())
+ {
+ int mode = getDebugDrawer()->getDebugMode();
+ if(mode & (btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits))
+ {
+ drawConstraints = true;
+ }
+ }
+ if(drawConstraints)
+ {
+ for(int i = getNumConstraints()-1; i>=0 ;i--)
+ {
+ btTypedConstraint* constraint = getConstraint(i);
+ debugDrawConstraint(constraint);
+ }
+ }
+
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb))
{
int i;
- //todo: iterate over awake simulation islands!
for ( i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
@@ -179,7 +196,7 @@ void btDiscreteDynamicsWorld::debugDrawWorld()
}
if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
{
- btPoint3 minAabb,maxAabb;
+ btVector3 minAabb,maxAabb;
btVector3 colorvec(1,0,0);
colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec);
@@ -187,32 +204,11 @@ void btDiscreteDynamicsWorld::debugDrawWorld()
}
- for ( i=0;i<this->m_vehicles.size();i++)
+ if (getDebugDrawer() && getDebugDrawer()->getDebugMode())
{
- for (int v=0;v<m_vehicles[i]->getNumWheels();v++)
+ for (i=0;i<m_actions.size();i++)
{
- btVector3 wheelColor(0,255,255);
- if (m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_isInContact)
- {
- wheelColor.setValue(0,0,255);
- } else
- {
- wheelColor.setValue(255,0,255);
- }
-
- btVector3 wheelPosWS = m_vehicles[i]->getWheelInfo(v).m_worldTransform.getOrigin();
-
- btVector3 axle = btVector3(
- m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[0][m_vehicles[i]->getRightAxis()],
- m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[1][m_vehicles[i]->getRightAxis()],
- m_vehicles[i]->getWheelInfo(v).m_worldTransform.getBasis()[2][m_vehicles[i]->getRightAxis()]);
-
-
- //m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_wheelAxleWS
- //debug wheels (cylinders)
- m_debugDrawer->drawLine(wheelPosWS,wheelPosWS+axle,wheelColor);
- m_debugDrawer->drawLine(wheelPosWS,m_vehicles[i]->getWheelInfo(v).m_raycastInfo.m_contactPointWS,wheelColor);
-
+ m_actions[i]->debugDraw(m_debugDrawer);
}
}
}
@@ -220,7 +216,7 @@ void btDiscreteDynamicsWorld::debugDrawWorld()
void btDiscreteDynamicsWorld::clearForces()
{
- //todo: iterate over awake simulation islands!
+ ///@todo: iterate over awake simulation islands!
for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
@@ -236,7 +232,7 @@ void btDiscreteDynamicsWorld::clearForces()
///apply gravity, call this once per timestep
void btDiscreteDynamicsWorld::applyGravity()
{
- //todo: iterate over awake simulation islands!
+ ///@todo: iterate over awake simulation islands!
for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
@@ -250,9 +246,29 @@ void btDiscreteDynamicsWorld::applyGravity()
}
+void btDiscreteDynamicsWorld::synchronizeSingleMotionState(btRigidBody* body)
+{
+ btAssert(body);
+
+ if (body->getMotionState() && !body->isStaticOrKinematicObject())
+ {
+ //we need to call the update at least once, even for sleeping objects
+ //otherwise the 'graphics' transform never updates properly
+ ///@todo: add 'dirty' flag
+ //if (body->getActivationState() != ISLAND_SLEEPING)
+ {
+ btTransform interpolatedTransform;
+ btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
+ body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime*body->getHitFraction(),interpolatedTransform);
+ body->getMotionState()->setWorldTransform(interpolatedTransform);
+ }
+ }
+}
+
void btDiscreteDynamicsWorld::synchronizeMotionStates()
{
+ BT_PROFILE("synchronizeMotionStates");
{
//todo: iterate over awake simulation islands!
for ( int i=0;i<m_collisionObjects.size();i++)
@@ -260,22 +276,11 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates()
btCollisionObject* colObj = m_collisionObjects[i];
btRigidBody* body = btRigidBody::upcast(colObj);
- if (body && body->getMotionState() && !body->isStaticOrKinematicObject())
- {
- //we need to call the update at least once, even for sleeping objects
- //otherwise the 'graphics' transform never updates properly
- //so todo: add 'dirty' flag
- //if (body->getActivationState() != ISLAND_SLEEPING)
- {
- btTransform interpolatedTransform;
- btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
- body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime*body->getHitFraction(),interpolatedTransform);
- body->getMotionState()->setWorldTransform(interpolatedTransform);
- }
- }
+ if (body)
+ synchronizeSingleMotionState(body);
}
}
-
+/*
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)
{
for ( int i=0;i<this->m_vehicles.size();i++)
@@ -287,6 +292,8 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates()
}
}
}
+ */
+
}
@@ -327,7 +334,8 @@ int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps,
//process some debugging flags
if (getDebugDrawer())
{
- gDisableDeactivation = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
+ btIDebugDraw* debugDrawer = getDebugDrawer ();
+ gDisableDeactivation = (debugDrawer->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
}
if (numSimulationSubSteps)
{
@@ -391,9 +399,8 @@ void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
integrateTransforms(timeStep);
///update vehicle simulation
- updateVehicles(timeStep);
-
-
+ updateActions(timeStep);
+
updateActivationState( timeStep );
if(0 != m_internalTickCallback) {
@@ -423,13 +430,6 @@ btVector3 btDiscreteDynamicsWorld::getGravity () const
void btDiscreteDynamicsWorld::removeRigidBody(btRigidBody* body)
{
- //remove all constraints too
- while (body->getNumConstraintRefs())
- {
- btTypedConstraint* constraint = body->getConstraintRef(0);
- removeConstraint(constraint);
- }
-
removeCollisionObject(body);
}
@@ -464,17 +464,17 @@ void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, short group, short
}
-void btDiscreteDynamicsWorld::updateVehicles(btScalar timeStep)
+void btDiscreteDynamicsWorld::updateActions(btScalar timeStep)
{
- BT_PROFILE("updateVehicles");
+ BT_PROFILE("updateActions");
- for ( int i=0;i<m_vehicles.size();i++)
+ for ( int i=0;i<m_actions.size();i++)
{
- btRaycastVehicle* vehicle = m_vehicles[i];
- vehicle->updateVehicle( timeStep);
+ m_actions[i]->updateAction( this, timeStep);
}
}
-
+
+
void btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep)
{
BT_PROFILE("updateActivationState");
@@ -529,16 +529,38 @@ void btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint)
constraint->getRigidBodyB().removeConstraintRef(constraint);
}
-void btDiscreteDynamicsWorld::addVehicle(btRaycastVehicle* vehicle)
+void btDiscreteDynamicsWorld::addAction(btActionInterface* action)
+{
+ m_actions.push_back(action);
+}
+
+void btDiscreteDynamicsWorld::removeAction(btActionInterface* action)
+{
+ m_actions.remove(action);
+}
+
+
+void btDiscreteDynamicsWorld::addVehicle(btActionInterface* vehicle)
+{
+ addAction(vehicle);
+}
+
+void btDiscreteDynamicsWorld::removeVehicle(btActionInterface* vehicle)
+{
+ removeAction(vehicle);
+}
+
+void btDiscreteDynamicsWorld::addCharacter(btActionInterface* character)
{
- m_vehicles.push_back(vehicle);
+ addAction(character);
}
-void btDiscreteDynamicsWorld::removeVehicle(btRaycastVehicle* vehicle)
+void btDiscreteDynamicsWorld::removeCharacter(btActionInterface* character)
{
- m_vehicles.remove(vehicle);
+ removeAction(character);
}
+
SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs)
{
int islandId;
@@ -611,8 +633,11 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
{
if (islandId<0)
{
- ///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id
- m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
+ if (numManifolds + m_numConstraints)
+ {
+ ///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id
+ m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
+ }
} else
{
//also add all non-contact constraints/joints for this island
@@ -658,7 +683,7 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
sortedConstraints[i] = m_constraints[i];
}
-// assert(0);
+// btAssert(0);
@@ -671,7 +696,7 @@ void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds());
/// solve all the constraints for this island
- m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld()->getCollisionObjectArray(),&solverCallback);
+ m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld(),&solverCallback);
m_constraintSolver->allSolved(solverInfo, m_debugDrawer, m_stackAlloc);
}
@@ -722,21 +747,27 @@ class btClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConve
btCollisionObject* m_me;
btScalar m_allowedPenetration;
btOverlappingPairCache* m_pairCache;
+ btDispatcher* m_dispatcher;
public:
- btClosestNotMeConvexResultCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache) :
+ btClosestNotMeConvexResultCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
btCollisionWorld::ClosestConvexResultCallback(fromA,toA),
m_allowedPenetration(0.0f),
m_me(me),
- m_pairCache(pairCache)
+ m_pairCache(pairCache),
+ m_dispatcher(dispatcher)
{
}
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
{
if (convexResult.m_hitCollisionObject == m_me)
- return 1.0;
+ return 1.0f;
+
+ //ignore result if there is no contact response
+ if(!convexResult.m_hitCollisionObject->hasContactResponse())
+ return 1.0f;
btVector3 linVelA,linVelB;
linVelA = m_convexToWorld-m_convexFromWorld;
@@ -757,23 +788,29 @@ public:
return false;
///don't do CCD when the collision filters are not matching
- if (!btCollisionWorld::ClosestConvexResultCallback::needsCollision(proxy0))
+ if (!ClosestConvexResultCallback::needsCollision(proxy0))
return false;
- ///don't do CCD when there are already contact points (touching contact/penetration)
- btAlignedObjectArray<btPersistentManifold*> manifoldArray;
- btBroadphasePair* collisionPair = m_pairCache->findPair(m_me->getBroadphaseHandle(),proxy0);
- if (collisionPair)
+ btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
+
+ //call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179
+ if (m_dispatcher->needsResponse(m_me,otherObj))
{
- if (collisionPair->m_algorithm)
+ ///don't do CCD when there are already contact points (touching contact/penetration)
+ btAlignedObjectArray<btPersistentManifold*> manifoldArray;
+ btBroadphasePair* collisionPair = m_pairCache->findPair(m_me->getBroadphaseHandle(),proxy0);
+ if (collisionPair)
{
- manifoldArray.resize(0);
- collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
- for (int j=0;j<manifoldArray.size();j++)
+ if (collisionPair->m_algorithm)
{
- btPersistentManifold* manifold = manifoldArray[j];
- if (manifold->getNumContacts()>0)
- return false;
+ manifoldArray.resize(0);
+ collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
+ for (int j=0;j<manifoldArray.size();j++)
+ {
+ btPersistentManifold* manifold = manifoldArray[j];
+ if (manifold->getNumContacts()>0)
+ return false;
+ }
}
}
}
@@ -811,9 +848,13 @@ void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep)
{
gNumClampedCcdMotions++;
- btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache());
+ btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
+
+ sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
+ sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
+
convexSweepTest(&tmpSphere,body->getWorldTransform(),predictedTrans,sweepResults);
if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
{
@@ -833,6 +874,8 @@ void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep)
+
+
void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
{
BT_PROFILE("predictUnconstraintMotion");
@@ -844,14 +887,12 @@ void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
{
if (!body->isStaticOrKinematicObject())
{
- if (body->isActive())
- {
- body->integrateVelocities( timeStep);
- //damping
- body->applyDamping(timeStep);
+
+ body->integrateVelocities( timeStep);
+ //damping
+ body->applyDamping(timeStep);
- body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
- }
+ body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
}
}
}
@@ -1103,7 +1144,7 @@ void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform,
{
btConcaveShape* concaveMesh = (btConcaveShape*) shape;
- //todo pass camera, for some culling
+ ///@todo pass camera, for some culling? no -> we are not a graphics lib
btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
@@ -1132,7 +1173,7 @@ void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform,
int i;
for (i=0;i<polyshape->getNumEdges();i++)
{
- btPoint3 a,b;
+ btVector3 a,b;
polyshape->getEdge(i,a,b);
btVector3 wa = worldTransform * a;
btVector3 wb = worldTransform * b;
@@ -1148,6 +1189,189 @@ void btDiscreteDynamicsWorld::debugDrawObject(const btTransform& worldTransform,
}
+void btDiscreteDynamicsWorld::debugDrawConstraint(btTypedConstraint* constraint)
+{
+ bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0;
+ bool drawLimits = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraintLimits) != 0;
+ btScalar dbgDrawSize = constraint->getDbgDrawSize();
+ if(dbgDrawSize <= btScalar(0.f))
+ {
+ return;
+ }
+
+ switch(constraint->getConstraintType())
+ {
+ case POINT2POINT_CONSTRAINT_TYPE:
+ {
+ btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint;
+ btTransform tr;
+ tr.setIdentity();
+ btVector3 pivot = p2pC->getPivotInA();
+ pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot;
+ tr.setOrigin(pivot);
+ getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ // that ideally should draw the same frame
+ pivot = p2pC->getPivotInB();
+ pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot;
+ tr.setOrigin(pivot);
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ }
+ break;
+ case HINGE_CONSTRAINT_TYPE:
+ {
+ btHingeConstraint* pHinge = (btHingeConstraint*)constraint;
+ btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame();
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame();
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ btScalar minAng = pHinge->getLowerLimit();
+ btScalar maxAng = pHinge->getUpperLimit();
+ if(minAng == maxAng)
+ {
+ break;
+ }
+ bool drawSect = true;
+ if(minAng > maxAng)
+ {
+ minAng = btScalar(0.f);
+ maxAng = SIMD_2_PI;
+ drawSect = false;
+ }
+ if(drawLimits)
+ {
+ btVector3& center = tr.getOrigin();
+ btVector3 normal = tr.getBasis().getColumn(2);
+ btVector3 axis = tr.getBasis().getColumn(0);
+ getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0,0,0), drawSect);
+ }
+ }
+ break;
+ case CONETWIST_CONSTRAINT_TYPE:
+ {
+ btConeTwistConstraint* pCT = (btConeTwistConstraint*)constraint;
+ btTransform tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ if(drawLimits)
+ {
+ //const btScalar length = btScalar(5);
+ const btScalar length = dbgDrawSize;
+ static int nSegments = 8*4;
+ btScalar fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)(nSegments-1)/btScalar(nSegments);
+ btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length);
+ pPrev = tr * pPrev;
+ for (int i=0; i<nSegments; i++)
+ {
+ fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)i/btScalar(nSegments);
+ btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length);
+ pCur = tr * pCur;
+ getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0,0,0));
+
+ if (i%(nSegments/8) == 0)
+ getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0,0,0));
+
+ pPrev = pCur;
+ }
+ btScalar tws = pCT->getTwistSpan();
+ btScalar twa = pCT->getTwistAngle();
+ bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f));
+ if(useFrameB)
+ {
+ tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
+ }
+ else
+ {
+ tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
+ }
+ btVector3 pivot = tr.getOrigin();
+ btVector3 normal = tr.getBasis().getColumn(0);
+ btVector3 axis1 = tr.getBasis().getColumn(1);
+ getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa-tws, -twa+tws, btVector3(0,0,0), true);
+
+ }
+ }
+ break;
+ case D6_CONSTRAINT_TYPE:
+ {
+ btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)constraint;
+ btTransform tr = p6DOF->getCalculatedTransformA();
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ tr = p6DOF->getCalculatedTransformB();
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ if(drawLimits)
+ {
+ tr = p6DOF->getCalculatedTransformA();
+ const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
+ btVector3 up = tr.getBasis().getColumn(2);
+ btVector3 axis = tr.getBasis().getColumn(0);
+ btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
+ btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
+ btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
+ btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
+ getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0,0,0));
+ axis = tr.getBasis().getColumn(1);
+ btScalar ay = p6DOF->getAngle(1);
+ btScalar az = p6DOF->getAngle(2);
+ btScalar cy = btCos(ay);
+ btScalar sy = btSin(ay);
+ btScalar cz = btCos(az);
+ btScalar sz = btSin(az);
+ btVector3 ref;
+ ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2];
+ ref[1] = -sz*axis[0] + cz*axis[1];
+ ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2];
+ tr = p6DOF->getCalculatedTransformB();
+ btVector3 normal = -tr.getBasis().getColumn(0);
+ btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
+ btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
+ if(minFi > maxFi)
+ {
+ getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0,0,0), false);
+ }
+ else if(minFi < maxFi)
+ {
+ getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0,0,0), true);
+ }
+ tr = p6DOF->getCalculatedTransformA();
+ btVector3 bbMin = p6DOF->getTranslationalLimitMotor()->m_lowerLimit;
+ btVector3 bbMax = p6DOF->getTranslationalLimitMotor()->m_upperLimit;
+ getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0,0,0));
+ }
+ }
+ break;
+ case SLIDER_CONSTRAINT_TYPE:
+ {
+ btSliderConstraint* pSlider = (btSliderConstraint*)constraint;
+ btTransform tr = pSlider->getCalculatedTransformA();
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ tr = pSlider->getCalculatedTransformB();
+ if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+ if(drawLimits)
+ {
+ btTransform tr = pSlider->getCalculatedTransformA();
+ btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f);
+ btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f);
+ getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0));
+ btVector3 normal = tr.getBasis().getColumn(0);
+ btVector3 axis = tr.getBasis().getColumn(1);
+ btScalar a_min = pSlider->getLowerAngLimit();
+ btScalar a_max = pSlider->getUpperAngLimit();
+ const btVector3& center = pSlider->getCalculatedTransformB().getOrigin();
+ getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0,0,0), true);
+ }
+ }
+ break;
+ default :
+ break;
+ }
+ return;
+} // btDiscreteDynamicsWorld::debugDrawConstraint()
+
+
+
+
+
void btDiscreteDynamicsWorld::setConstraintSolver(btConstraintSolver* solver)
{
if (m_ownsConstraintSolver)
@@ -1176,3 +1400,5 @@ const btTypedConstraint* btDiscreteDynamicsWorld::getConstraint(int index) const
{
return m_constraints[index];
}
+
+
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
index d9e2652aaf6..4662cf5052a 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
@@ -23,9 +23,8 @@ class btOverlappingPairCache;
class btConstraintSolver;
class btSimulationIslandManager;
class btTypedConstraint;
+class btActionInterface;
-
-class btRaycastVehicle;
class btIDebugDraw;
#include "LinearMath/btAlignedObjectArray.h"
@@ -42,7 +41,6 @@ protected:
btAlignedObjectArray<btTypedConstraint*> m_constraints;
-
btVector3 m_gravity;
//for variable timesteps
@@ -52,33 +50,32 @@ protected:
bool m_ownsIslandManager;
bool m_ownsConstraintSolver;
+ btAlignedObjectArray<btActionInterface*> m_actions;
- btAlignedObjectArray<btRaycastVehicle*> m_vehicles;
-
int m_profileTimings;
virtual void predictUnconstraintMotion(btScalar timeStep);
virtual void integrateTransforms(btScalar timeStep);
- void calculateSimulationIslands();
+ virtual void calculateSimulationIslands();
- void solveConstraints(btContactSolverInfo& solverInfo);
+ virtual void solveConstraints(btContactSolverInfo& solverInfo);
void updateActivationState(btScalar timeStep);
- void updateVehicles(btScalar timeStep);
+ void updateActions(btScalar timeStep);
void startProfiling(btScalar timeStep);
virtual void internalSingleStepSimulation( btScalar timeStep);
- void synchronizeMotionStates();
- void saveKinematicState(btScalar timeStep);
+ virtual void saveKinematicState(btScalar timeStep);
void debugDrawSphere(btScalar radius, const btTransform& transform, const btVector3& color);
+
public:
@@ -91,14 +88,19 @@ public:
virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
- void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false);
+ virtual void synchronizeMotionStates();
- void removeConstraint(btTypedConstraint* constraint);
+ ///this can be useful to synchronize a single rigid body -> graphics object
+ void synchronizeSingleMotionState(btRigidBody* body);
- void addVehicle(btRaycastVehicle* vehicle);
+ virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false);
- void removeVehicle(btRaycastVehicle* vehicle);
+ virtual void removeConstraint(btTypedConstraint* constraint);
+ virtual void addAction(btActionInterface*);
+
+ virtual void removeAction(btActionInterface*);
+
btSimulationIslandManager* getSimulationIslandManager()
{
return m_islandManager;
@@ -114,8 +116,8 @@ public:
return this;
}
-
virtual void setGravity(const btVector3& gravity);
+
virtual btVector3 getGravity () const;
virtual void addRigidBody(btRigidBody* body);
@@ -126,6 +128,8 @@ public:
void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color);
+ void debugDrawConstraint(btTypedConstraint* constraint);
+
virtual void debugDrawWorld();
virtual void setConstraintSolver(btConstraintSolver* solver);
@@ -152,8 +156,24 @@ public:
virtual void setNumTasks(int numTasks)
{
+ (void) numTasks;
+ }
+
+ ///obsolete, use updateActions instead
+ virtual void updateVehicles(btScalar timeStep)
+ {
+ updateActions(timeStep);
}
+ ///obsolete, use addAction instead
+ virtual void addVehicle(btActionInterface* vehicle);
+ ///obsolete, use removeAction instead
+ virtual void removeVehicle(btActionInterface* vehicle);
+ ///obsolete, use addAction instead
+ virtual void addCharacter(btActionInterface* character);
+ ///obsolete, use removeAction instead
+ virtual void removeCharacter(btActionInterface* character);
+
};
#endif //BT_DISCRETE_DYNAMICS_WORLD_H
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h
index 929e24d337c..ecf7a2f0c64 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h
@@ -20,10 +20,11 @@ subject to the following restrictions:
#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
class btTypedConstraint;
-class btRaycastVehicle;
+class btActionInterface;
class btConstraintSolver;
class btDynamicsWorld;
+
/// Type for the callback for each tick
typedef void (*btInternalTickCallback)(btDynamicsWorld *world, btScalar timeStep);
@@ -71,15 +72,17 @@ public:
virtual void removeConstraint(btTypedConstraint* constraint) {(void)constraint;}
- virtual void addVehicle(btRaycastVehicle* vehicle) {(void)vehicle;}
+ virtual void addAction(btActionInterface* action) = 0;
- virtual void removeVehicle(btRaycastVehicle* vehicle) {(void)vehicle;}
+ virtual void removeAction(btActionInterface* action) = 0;
//once a rigidbody is added to the dynamics world, it will get this gravity assigned
//existing rigidbodies in the world get gravity assigned too, during this method
virtual void setGravity(const btVector3& gravity) = 0;
virtual btVector3 getGravity () const = 0;
+ virtual void synchronizeMotionStates() = 0;
+
virtual void addRigidBody(btRigidBody* body) = 0;
virtual void removeRigidBody(btRigidBody* body) = 0;
@@ -121,6 +124,16 @@ public:
}
+ ///obsolete, use addAction instead.
+ virtual void addVehicle(btActionInterface* vehicle) {(void)vehicle;}
+ ///obsolete, use removeAction instead
+ virtual void removeVehicle(btActionInterface* vehicle) {(void)vehicle;}
+ ///obsolete, use addAction instead.
+ virtual void addCharacter(btActionInterface* character) {(void)character;}
+ ///obsolete, use removeAction instead
+ virtual void removeCharacter(btActionInterface* character) {(void)character;}
+
+
};
#endif //BT_DYNAMICS_WORLD_H
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
index 93d70de39d8..a4d8e1d77f6 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
@@ -44,9 +44,10 @@ void btRigidBody::setupRigidBody(const btRigidBody::btRigidBodyConstructionInfo&
m_linearVelocity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
- m_angularFactor = btScalar(1.);
- m_anisotropicFriction.setValue(1.f,1.f,1.f);
+ m_angularFactor.setValue(1,1,1);
+ m_linearFactor.setValue(1,1,1);
m_gravity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
+ m_gravity_acceleration.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)),
m_linearDamping = btScalar(0.);
@@ -125,6 +126,7 @@ void btRigidBody::setGravity(const btVector3& acceleration)
{
m_gravity = acceleration * (btScalar(1.0) / m_inverseMass);
}
+ m_gravity_acceleration = acceleration;
}
@@ -144,8 +146,17 @@ void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping)
///applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping
void btRigidBody::applyDamping(btScalar timeStep)
{
+ //On new damping: see discussion/issue report here: http://code.google.com/p/bullet/issues/detail?id=74
+ //todo: do some performance comparisons (but other parts of the engine are probably bottleneck anyway
+
+//#define USE_OLD_DAMPING_METHOD 1
+#ifdef USE_OLD_DAMPING_METHOD
m_linearVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
m_angularVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
+#else
+ m_linearVelocity *= btPow(btScalar(1)-m_linearDamping, timeStep);
+ m_angularVelocity *= btPow(btScalar(1)-m_angularDamping, timeStep);
+#endif
if (m_additionalDamping)
{
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
index 4596f90a00f..da1fcb78611 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
@@ -17,7 +17,6 @@ subject to the following restrictions:
#define RIGIDBODY_H
#include "LinearMath/btAlignedObjectArray.h"
-#include "LinearMath/btPoint3.h"
#include "LinearMath/btTransform.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
@@ -31,7 +30,7 @@ extern btScalar gDeactivationTime;
extern bool gDisableDeactivation;
-///btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape.
+///The btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape.
///It is recommended for performance and memory use to share btCollisionShape objects whenever possible.
///There are 3 types of rigid bodies:
///- A) Dynamic rigid bodies, with positive mass. Motion is controlled by rigid body dynamics.
@@ -46,9 +45,11 @@ class btRigidBody : public btCollisionObject
btVector3 m_linearVelocity;
btVector3 m_angularVelocity;
btScalar m_inverseMass;
- btScalar m_angularFactor;
+ btVector3 m_angularFactor;
+ btVector3 m_linearFactor;
btVector3 m_gravity;
+ btVector3 m_gravity_acceleration;
btVector3 m_invInertiaLocal;
btVector3 m_totalForce;
btVector3 m_totalTorque;
@@ -75,7 +76,7 @@ class btRigidBody : public btCollisionObject
public:
- ///btRigidBodyConstructionInfo provides information to create a rigid body. Setting mass to zero creates a fixed (non-dynamic) rigid body.
+ ///The btRigidBodyConstructionInfo structure provides information to create a rigid body. Setting mass to zero creates a fixed (non-dynamic) rigid body.
///For dynamic objects, you can use the collision shape to approximate the local inertia tensor, otherwise use the zero vector (default argument)
///You can use the motion state to synchronize the world transform between physics and graphics objects.
///And if the motion state is provided, the rigid body will initialize its initial world transform from the motion state,
@@ -182,7 +183,7 @@ public:
const btVector3& getGravity() const
{
- return m_gravity;
+ return m_gravity_acceleration;
}
void setDamping(btScalar lin_damping, btScalar ang_damping);
@@ -219,6 +220,14 @@ public:
void setMassProps(btScalar mass, const btVector3& inertia);
+ const btVector3& getLinearFactor() const
+ {
+ return m_linearFactor;
+ }
+ void setLinearFactor(const btVector3& linearFactor)
+ {
+ m_linearFactor = linearFactor;
+ }
btScalar getInvMass() const { return m_inverseMass; }
const btMatrix3x3& getInvInertiaTensorWorld() const {
return m_invInertiaTensorWorld;
@@ -230,10 +239,20 @@ public:
void applyCentralForce(const btVector3& force)
{
- m_totalForce += force;
+ m_totalForce += force*m_linearFactor;
}
+
+ const btVector3& getTotalForce()
+ {
+ return m_totalForce;
+ };
+
+ const btVector3& getTotalTorque()
+ {
+ return m_totalTorque;
+ };
- const btVector3& getInvInertiaDiagLocal()
+ const btVector3& getInvInertiaDiagLocal() const
{
return m_invInertiaLocal;
};
@@ -251,23 +270,23 @@ public:
void applyTorque(const btVector3& torque)
{
- m_totalTorque += torque;
+ m_totalTorque += torque*m_angularFactor;
}
void applyForce(const btVector3& force, const btVector3& rel_pos)
{
applyCentralForce(force);
- applyTorque(rel_pos.cross(force)*m_angularFactor);
+ applyTorque(rel_pos.cross(force*m_linearFactor));
}
void applyCentralImpulse(const btVector3& impulse)
{
- m_linearVelocity += impulse * m_inverseMass;
+ m_linearVelocity += impulse *m_linearFactor * m_inverseMass;
}
void applyTorqueImpulse(const btVector3& torque)
{
- m_angularVelocity += m_invInertiaTensorWorld * torque;
+ m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
}
void applyImpulse(const btVector3& impulse, const btVector3& rel_pos)
@@ -277,7 +296,7 @@ public:
applyCentralImpulse(impulse);
if (m_angularFactor)
{
- applyTorqueImpulse(rel_pos.cross(impulse)*m_angularFactor);
+ applyTorqueImpulse(rel_pos.cross(impulse*m_linearFactor));
}
}
}
@@ -287,10 +306,10 @@ public:
{
if (m_inverseMass != btScalar(0.))
{
- m_linearVelocity += linearComponent*impulseMagnitude;
+ m_linearVelocity += linearComponent*m_linearFactor*impulseMagnitude;
if (m_angularFactor)
{
- m_angularVelocity += angularComponent*impulseMagnitude*m_angularFactor;
+ m_angularVelocity += angularComponent*m_angularFactor*impulseMagnitude;
}
}
}
@@ -303,7 +322,7 @@ public:
void updateInertiaTensor();
- const btPoint3& getCenterOfMassPosition() const {
+ const btVector3& getCenterOfMassPosition() const {
return m_worldTransform.getOrigin();
}
btQuaternion getOrientation() const;
@@ -321,15 +340,12 @@ public:
inline void setLinearVelocity(const btVector3& lin_vel)
{
- assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT);
m_linearVelocity = lin_vel;
}
- inline void setAngularVelocity(const btVector3& ang_vel) {
- assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT);
- {
- m_angularVelocity = ang_vel;
- }
+ inline void setAngularVelocity(const btVector3& ang_vel)
+ {
+ m_angularVelocity = ang_vel;
}
btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const
@@ -353,7 +369,7 @@ public:
- SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btPoint3& pos, const btVector3& normal) const
+ SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btVector3& pos, const btVector3& normal) const
{
btVector3 r0 = pos - getCenterOfMassPosition();
@@ -443,11 +459,16 @@ public:
int m_contactSolverType;
int m_frictionSolverType;
- void setAngularFactor(btScalar angFac)
+ void setAngularFactor(const btVector3& angFac)
{
m_angularFactor = angFac;
}
- btScalar getAngularFactor() const
+
+ void setAngularFactor(btScalar angFac)
+ {
+ m_angularFactor.setValue(angFac,angFac,angFac);
+ }
+ const btVector3& getAngularFactor() const
{
return m_angularFactor;
}
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
index 3be04d1a4ad..3f6141463c3 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
@@ -97,7 +97,7 @@ int btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, b
void btSimpleDynamicsWorld::clearForces()
{
- //todo: iterate over awake simulation islands!
+ ///@todo: iterate over awake simulation islands!
for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
@@ -156,7 +156,7 @@ void btSimpleDynamicsWorld::updateAabbs()
{
if (body->isActive() && (!body->isStaticObject()))
{
- btPoint3 minAabb,maxAabb;
+ btVector3 minAabb,maxAabb;
colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
btBroadphaseInterface* bp = getBroadphase();
bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
@@ -210,7 +210,7 @@ void btSimpleDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
void btSimpleDynamicsWorld::synchronizeMotionStates()
{
- //todo: iterate over awake simulation islands!
+ ///@todo: iterate over awake simulation islands!
for ( int i=0;i<m_collisionObjects.size();i++)
{
btCollisionObject* colObj = m_collisionObjects[i];
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
index 5c56fdf1327..ea1a2a1ccc7 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
@@ -22,7 +22,7 @@ class btDispatcher;
class btOverlappingPairCache;
class btConstraintSolver;
-///btSimpleDynamicsWorld serves as unit-test and to verify more complicated and optimized dynamics worlds.
+///The btSimpleDynamicsWorld serves as unit-test and to verify more complicated and optimized dynamics worlds.
///Please use btDiscreteDynamicsWorld instead (or btContinuousDynamicsWorld once it is finished).
class btSimpleDynamicsWorld : public btDynamicsWorld
{
@@ -60,7 +60,7 @@ public:
virtual void updateAabbs();
- void synchronizeMotionStates();
+ virtual void synchronizeMotionStates();
virtual void setConstraintSolver(btConstraintSolver* solver);
diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
index fe65245c2a1..031fcb5b447 100644
--- a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
+++ b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
@@ -19,15 +19,13 @@
#include "btVehicleRaycaster.h"
#include "btWheelInfo.h"
#include "LinearMath/btMinMax.h"
-
-
+#include "LinearMath/btIDebugDraw.h"
#include "BulletDynamics/ConstraintSolver/btContactConstraint.h"
static btRigidBody s_fixedObject( 0,0,0);
btRaycastVehicle::btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis, btVehicleRaycaster* raycaster )
-: btTypedConstraint(VEHICLE_CONSTRAINT_TYPE),
-m_vehicleRaycaster(raycaster),
+:m_vehicleRaycaster(raycaster),
m_pitchControl(btScalar(0.))
{
m_chassisBody = chassis;
@@ -87,7 +85,7 @@ btWheelInfo& btRaycastVehicle::addWheel( const btVector3& connectionPointCS, con
const btTransform& btRaycastVehicle::getWheelTransformWS( int wheelIndex ) const
{
- assert(wheelIndex < getNumWheels());
+ btAssert(wheelIndex < getNumWheels());
const btWheelInfo& wheel = m_wheelInfo[wheelIndex];
return wheel.m_worldTransform;
@@ -175,7 +173,7 @@ btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel)
btVehicleRaycaster::btVehicleRaycasterResult rayResults;
- assert(m_vehicleRaycaster);
+ btAssert(m_vehicleRaycaster);
void* object = m_vehicleRaycaster->castRay(source,target,rayResults);
@@ -188,7 +186,7 @@ btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel)
wheel.m_raycastInfo.m_contactNormalWS = rayResults.m_hitNormalInWorld;
wheel.m_raycastInfo.m_isInContact = true;
- wheel.m_raycastInfo.m_groundObject = &s_fixedObject;//todo for driving on dynamic/movable objects!;
+ wheel.m_raycastInfo.m_groundObject = &s_fixedObject;///@todo for driving on dynamic/movable objects!;
//wheel.m_raycastInfo.m_groundObject = object;
@@ -359,7 +357,7 @@ void btRaycastVehicle::updateVehicle( btScalar step )
void btRaycastVehicle::setSteeringValue(btScalar steering,int wheel)
{
- assert(wheel>=0 && wheel < getNumWheels());
+ btAssert(wheel>=0 && wheel < getNumWheels());
btWheelInfo& wheelInfo = getWheelInfo(wheel);
wheelInfo.m_steering = steering;
@@ -375,7 +373,7 @@ btScalar btRaycastVehicle::getSteeringValue(int wheel) const
void btRaycastVehicle::applyEngineForce(btScalar force, int wheel)
{
- assert(wheel>=0 && wheel < getNumWheels());
+ btAssert(wheel>=0 && wheel < getNumWheels());
btWheelInfo& wheelInfo = getWheelInfo(wheel);
wheelInfo.m_engineForce = force;
}
@@ -691,7 +689,7 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
btVector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel];
- rel_pos[2] *= wheelInfo.m_rollInfluence;
+ rel_pos[m_indexUpAxis] *= wheelInfo.m_rollInfluence;
m_chassisBody->applyImpulse(sideImp,rel_pos);
//apply friction impulse on the ground
@@ -704,6 +702,36 @@ void btRaycastVehicle::updateFriction(btScalar timeStep)
}
+
+void btRaycastVehicle::debugDraw(btIDebugDraw* debugDrawer)
+{
+
+ for (int v=0;v<this->getNumWheels();v++)
+ {
+ btVector3 wheelColor(0,255,255);
+ if (getWheelInfo(v).m_raycastInfo.m_isInContact)
+ {
+ wheelColor.setValue(0,0,255);
+ } else
+ {
+ wheelColor.setValue(255,0,255);
+ }
+
+ btVector3 wheelPosWS = getWheelInfo(v).m_worldTransform.getOrigin();
+
+ btVector3 axle = btVector3(
+ getWheelInfo(v).m_worldTransform.getBasis()[0][getRightAxis()],
+ getWheelInfo(v).m_worldTransform.getBasis()[1][getRightAxis()],
+ getWheelInfo(v).m_worldTransform.getBasis()[2][getRightAxis()]);
+
+ //debug wheels (cylinders)
+ debugDrawer->drawLine(wheelPosWS,wheelPosWS+axle,wheelColor);
+ debugDrawer->drawLine(wheelPosWS,getWheelInfo(v).m_raycastInfo.m_contactPointWS,wheelColor);
+
+ }
+}
+
+
void* btDefaultVehicleRaycaster::castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result)
{
// RayResultCallback& resultCallback;
@@ -727,3 +755,4 @@ void* btDefaultVehicleRaycaster::castRay(const btVector3& from,const btVector3&
}
return 0;
}
+
diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h
index 8361dcabe4b..d5a299c606f 100644
--- a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h
+++ b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.h
@@ -17,11 +17,12 @@
class btDynamicsWorld;
#include "LinearMath/btAlignedObjectArray.h"
#include "btWheelInfo.h"
+#include "BulletDynamics/Dynamics/btActionInterface.h"
class btVehicleTuning;
///rayCast vehicle, very special constraint that turn a rigidbody into a vehicle.
-class btRaycastVehicle : public btTypedConstraint
+class btRaycastVehicle : public btActionInterface
{
btAlignedObjectArray<btVector3> m_forwardWS;
@@ -29,6 +30,11 @@ class btRaycastVehicle : public btTypedConstraint
btAlignedObjectArray<btScalar> m_forwardImpulse;
btAlignedObjectArray<btScalar> m_sideImpulse;
+ int m_userConstraintType;
+
+ int m_userConstraintId;
+
+
public:
class btVehicleTuning
{
@@ -73,13 +79,24 @@ public:
virtual ~btRaycastVehicle() ;
-
+
+ ///btActionInterface interface
+ virtual void updateAction( btCollisionWorld* collisionWorld, btScalar step)
+ {
+ updateVehicle(step);
+ }
+
+
+ ///btActionInterface interface
+ void debugDraw(btIDebugDraw* debugDrawer);
+
const btTransform& getChassisWorldTransform() const;
btScalar rayCast(btWheelInfo& wheel);
virtual void updateVehicle(btScalar step);
-
+
+
void resetSuspension();
btScalar getSteeringValue(int wheel) const;
@@ -175,15 +192,24 @@ public:
m_indexForwardAxis = forwardIndex;
}
- virtual void buildJacobian()
+ int getUserConstraintType() const
+ {
+ return m_userConstraintType ;
+ }
+
+ void setUserConstraintType(int userConstraintType)
+ {
+ m_userConstraintType = userConstraintType;
+ };
+
+ void setUserConstraintId(int uid)
{
- //not yet
+ m_userConstraintId = uid;
}
- virtual void solveConstraint(btScalar timeStep)
+ int getUserConstraintId() const
{
- (void)timeStep;
- //not yet
+ return m_userConstraintId;
}
diff --git a/extern/bullet2/src/BulletSoftBody/CMakeLists.txt b/extern/bullet2/src/BulletSoftBody/CMakeLists.txt
index a725e10ff77..dbd87afea38 100644
--- a/extern/bullet2/src/BulletSoftBody/CMakeLists.txt
+++ b/extern/bullet2/src/BulletSoftBody/CMakeLists.txt
@@ -3,19 +3,41 @@ INCLUDE_DIRECTORIES(
${BULLET_PHYSICS_SOURCE_DIR}/src }
)
-ADD_LIBRARY(LibBulletSoftBody
+SET(BulletSoftBody_SRCS
btSoftBody.cpp
- btSoftBody.h
btSoftBodyHelpers.cpp
- btSparseSDF.h
- btSoftBodyHelpers.h
btSoftBodyRigidBodyCollisionConfiguration.cpp
btSoftRigidCollisionAlgorithm.cpp
- btSoftRigidCollisionAlgorithm.h
btSoftSoftCollisionAlgorithm.cpp
- btSoftSoftCollisionAlgorithm.h
btSoftBodyConcaveCollisionAlgorithm.cpp
+ btSoftRigidDynamicsWorld.cpp
+)
+
+SET(BulletSoftBody_HDRS
+ btSoftBody.h
+ btSparseSDF.h
+ btSoftBodyHelpers.h
+ btSoftRigidCollisionAlgorithm.h
+ btSoftSoftCollisionAlgorithm.h
btSoftBodyConcaveCollisionAlgorithm.h
btSoftRigidDynamicsWorld.h
- btSoftRigidDynamicsWorld.cpp
)
+
+
+
+ADD_LIBRARY(BulletSoftBody ${BulletSoftBody_SRCS} ${BulletSoftBody_HDRS})
+SET_TARGET_PROPERTIES(BulletSoftBody PROPERTIES VERSION ${BULLET_VERSION})
+SET_TARGET_PROPERTIES(BulletSoftBody PROPERTIES SOVERSION ${BULLET_VERSION})
+IF (BUILD_SHARED_LIBS)
+ TARGET_LINK_LIBRARIES(BulletSoftBody BulletDynamics)
+ENDIF (BUILD_SHARED_LIBS)
+
+IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
+ INSTALL(TARGETS BulletSoftBody DESTINATION lib)
+ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h")
+ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
+
+IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
+ SET_TARGET_PROPERTIES(BulletSoftBody PROPERTIES FRAMEWORK true)
+ SET_TARGET_PROPERTIES(BulletSoftBody PROPERTIES PUBLIC_HEADER "${BulletSoftBody_HDRS}")
+ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp b/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp
index 1ec668c9c78..ee810c54082 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp
@@ -150,98 +150,98 @@ bool btSoftBody::checkFace(int node0,int node1,int node2) const
//
btSoftBody::Material* btSoftBody::appendMaterial()
{
-Material* pm=new(btAlignedAlloc(sizeof(Material),16)) Material();
-if(m_materials.size()>0)
- *pm=*m_materials[0];
+ Material* pm=new(btAlignedAlloc(sizeof(Material),16)) Material();
+ if(m_materials.size()>0)
+ *pm=*m_materials[0];
else
- ZeroInitialize(*pm);
-m_materials.push_back(pm);
-return(pm);
+ ZeroInitialize(*pm);
+ m_materials.push_back(pm);
+ return(pm);
}
//
void btSoftBody::appendNote( const char* text,
- const btVector3& o,
- const btVector4& c,
- Node* n0,
- Node* n1,
- Node* n2,
- Node* n3)
-{
-Note n;
-ZeroInitialize(n);
-n.m_rank = 0;
-n.m_text = text;
-n.m_offset = o;
-n.m_coords[0] = c.x();
-n.m_coords[1] = c.y();
-n.m_coords[2] = c.z();
-n.m_coords[3] = c.w();
-n.m_nodes[0] = n0;n.m_rank+=n0?1:0;
-n.m_nodes[1] = n1;n.m_rank+=n1?1:0;
-n.m_nodes[2] = n2;n.m_rank+=n2?1:0;
-n.m_nodes[3] = n3;n.m_rank+=n3?1:0;
-m_notes.push_back(n);
+ const btVector3& o,
+ const btVector4& c,
+ Node* n0,
+ Node* n1,
+ Node* n2,
+ Node* n3)
+{
+ Note n;
+ ZeroInitialize(n);
+ n.m_rank = 0;
+ n.m_text = text;
+ n.m_offset = o;
+ n.m_coords[0] = c.x();
+ n.m_coords[1] = c.y();
+ n.m_coords[2] = c.z();
+ n.m_coords[3] = c.w();
+ n.m_nodes[0] = n0;n.m_rank+=n0?1:0;
+ n.m_nodes[1] = n1;n.m_rank+=n1?1:0;
+ n.m_nodes[2] = n2;n.m_rank+=n2?1:0;
+ n.m_nodes[3] = n3;n.m_rank+=n3?1:0;
+ m_notes.push_back(n);
}
//
void btSoftBody::appendNote( const char* text,
- const btVector3& o,
- Node* feature)
+ const btVector3& o,
+ Node* feature)
{
-appendNote(text,o,btVector4(1,0,0,0),feature);
+ appendNote(text,o,btVector4(1,0,0,0),feature);
}
//
void btSoftBody::appendNote( const char* text,
- const btVector3& o,
- Link* feature)
+ const btVector3& o,
+ Link* feature)
{
-static const btScalar w=1/(btScalar)2;
-appendNote(text,o,btVector4(w,w,0,0), feature->m_n[0],
- feature->m_n[1]);
+ static const btScalar w=1/(btScalar)2;
+ appendNote(text,o,btVector4(w,w,0,0), feature->m_n[0],
+ feature->m_n[1]);
}
-
+
//
void btSoftBody::appendNote( const char* text,
- const btVector3& o,
- Face* feature)
+ const btVector3& o,
+ Face* feature)
{
-static const btScalar w=1/(btScalar)3;
-appendNote(text,o,btVector4(w,w,w,0), feature->m_n[0],
- feature->m_n[1],
- feature->m_n[2]);
+ static const btScalar w=1/(btScalar)3;
+ appendNote(text,o,btVector4(w,w,w,0), feature->m_n[0],
+ feature->m_n[1],
+ feature->m_n[2]);
}
//
void btSoftBody::appendNode( const btVector3& x,btScalar m)
{
-if(m_nodes.capacity()==m_nodes.size())
+ if(m_nodes.capacity()==m_nodes.size())
{
- pointersToIndices();
- m_nodes.reserve(m_nodes.size()*2+1);
- indicesToPointers();
+ pointersToIndices();
+ m_nodes.reserve(m_nodes.size()*2+1);
+ indicesToPointers();
}
-const btScalar margin=getCollisionShape()->getMargin();
-m_nodes.push_back(Node());
-Node& n=m_nodes[m_nodes.size()-1];
-ZeroInitialize(n);
-n.m_x = x;
-n.m_q = n.m_x;
-n.m_im = m>0?1/m:0;
-n.m_material = m_materials[0];
-n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x,margin),&n);
+ const btScalar margin=getCollisionShape()->getMargin();
+ m_nodes.push_back(Node());
+ Node& n=m_nodes[m_nodes.size()-1];
+ ZeroInitialize(n);
+ n.m_x = x;
+ n.m_q = n.m_x;
+ n.m_im = m>0?1/m:0;
+ n.m_material = m_materials[0];
+ n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x,margin),&n);
}
//
void btSoftBody::appendLink(int model,Material* mat)
{
-Link l;
-if(model>=0)
- l=m_links[model];
+ Link l;
+ if(model>=0)
+ l=m_links[model];
else
{ ZeroInitialize(l);l.m_material=mat?mat:m_materials[0]; }
-m_links.push_back(l);
+ m_links.push_back(l);
}
//
@@ -273,12 +273,12 @@ void btSoftBody::appendLink( Node* node0,
//
void btSoftBody::appendFace(int model,Material* mat)
{
-Face f;
-if(model>=0)
+ Face f;
+ if(model>=0)
{ f=m_faces[model]; }
else
{ ZeroInitialize(f);f.m_material=mat?mat:m_materials[0]; }
-m_faces.push_back(f);
+ m_faces.push_back(f);
}
//
@@ -306,9 +306,9 @@ void btSoftBody::appendFace(int node0,int node1,int node2,Material* mat)
}
//
-void btSoftBody::appendAnchor(int node,btRigidBody* body,bool disableCollisionWithBody=false)
+void btSoftBody::appendAnchor(int node,btRigidBody* body, bool disableCollisionBetweenLinkedBodies)
{
- if (disableCollisionWithBody)
+ if (disableCollisionBetweenLinkedBodies)
{
if (m_collisionDisabledObjects.findLinearSearch(body)==m_collisionDisabledObjects.size())
{
@@ -327,54 +327,54 @@ void btSoftBody::appendAnchor(int node,btRigidBody* body,bool disableCollision
//
void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1)
{
-LJoint* pj = new(btAlignedAlloc(sizeof(LJoint),16)) LJoint();
-pj->m_bodies[0] = body0;
-pj->m_bodies[1] = body1;
-pj->m_refs[0] = pj->m_bodies[0].xform().inverse()*specs.position;
-pj->m_refs[1] = pj->m_bodies[1].xform().inverse()*specs.position;
-pj->m_cfm = specs.cfm;
-pj->m_erp = specs.erp;
-pj->m_split = specs.split;
-m_joints.push_back(pj);
+ LJoint* pj = new(btAlignedAlloc(sizeof(LJoint),16)) LJoint();
+ pj->m_bodies[0] = body0;
+ pj->m_bodies[1] = body1;
+ pj->m_refs[0] = pj->m_bodies[0].xform().inverse()*specs.position;
+ pj->m_refs[1] = pj->m_bodies[1].xform().inverse()*specs.position;
+ pj->m_cfm = specs.cfm;
+ pj->m_erp = specs.erp;
+ pj->m_split = specs.split;
+ m_joints.push_back(pj);
}
//
void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,Body body)
{
-appendLinearJoint(specs,m_clusters[0],body);
+ appendLinearJoint(specs,m_clusters[0],body);
}
//
void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,btSoftBody* body)
{
-appendLinearJoint(specs,m_clusters[0],body->m_clusters[0]);
+ appendLinearJoint(specs,m_clusters[0],body->m_clusters[0]);
}
//
void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,Cluster* body0,Body body1)
{
-AJoint* pj = new(btAlignedAlloc(sizeof(AJoint),16)) AJoint();
-pj->m_bodies[0] = body0;
-pj->m_bodies[1] = body1;
-pj->m_refs[0] = pj->m_bodies[0].xform().inverse().getBasis()*specs.axis;
-pj->m_refs[1] = pj->m_bodies[1].xform().inverse().getBasis()*specs.axis;
-pj->m_cfm = specs.cfm;
-pj->m_erp = specs.erp;
-pj->m_split = specs.split;
-pj->m_icontrol = specs.icontrol;
-m_joints.push_back(pj);
+ AJoint* pj = new(btAlignedAlloc(sizeof(AJoint),16)) AJoint();
+ pj->m_bodies[0] = body0;
+ pj->m_bodies[1] = body1;
+ pj->m_refs[0] = pj->m_bodies[0].xform().inverse().getBasis()*specs.axis;
+ pj->m_refs[1] = pj->m_bodies[1].xform().inverse().getBasis()*specs.axis;
+ pj->m_cfm = specs.cfm;
+ pj->m_erp = specs.erp;
+ pj->m_split = specs.split;
+ pj->m_icontrol = specs.icontrol;
+ m_joints.push_back(pj);
}
//
void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,Body body)
{
-appendAngularJoint(specs,m_clusters[0],body);
+ appendAngularJoint(specs,m_clusters[0],body);
}
//
void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,btSoftBody* body)
{
-appendAngularJoint(specs,m_clusters[0],body->m_clusters[0]);
+ appendAngularJoint(specs,m_clusters[0],body->m_clusters[0]);
}
//
@@ -463,8 +463,8 @@ void btSoftBody::setTotalMass(btScalar mass,bool fromfaces)
{
const Face& f=m_faces[i];
const btScalar twicearea=AreaOf( f.m_n[0]->m_x,
- f.m_n[1]->m_x,
- f.m_n[2]->m_x);
+ f.m_n[1]->m_x,
+ f.m_n[2]->m_x);
for(int j=0;j<3;++j)
{
f.m_n[j]->m_im+=twicearea;
@@ -494,13 +494,17 @@ void btSoftBody::setTotalDensity(btScalar density)
void btSoftBody::transform(const btTransform& trs)
{
const btScalar margin=getCollisionShape()->getMargin();
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) vol;
+
for(int i=0,ni=m_nodes.size();i<ni;++i)
{
Node& n=m_nodes[i];
n.m_x=trs*n.m_x;
n.m_q=trs*n.m_q;
n.m_n=trs.getBasis()*n.m_n;
- m_ndbvt.update(n.m_leaf,btDbvtVolume::FromCR(n.m_x,margin));
+ vol = btDbvtVolume::FromCR(n.m_x,margin);
+
+ m_ndbvt.update(n.m_leaf,vol);
}
updateNormals();
updateBounds();
@@ -511,31 +515,34 @@ void btSoftBody::transform(const btTransform& trs)
//
void btSoftBody::translate(const btVector3& trs)
{
-btTransform t;
-t.setIdentity();
-t.setOrigin(trs);
-transform(t);
+ btTransform t;
+ t.setIdentity();
+ t.setOrigin(trs);
+ transform(t);
}
//
void btSoftBody::rotate( const btQuaternion& rot)
{
-btTransform t;
-t.setIdentity();
-t.setRotation(rot);
-transform(t);
+ btTransform t;
+ t.setIdentity();
+ t.setRotation(rot);
+ transform(t);
}
//
void btSoftBody::scale(const btVector3& scl)
{
const btScalar margin=getCollisionShape()->getMargin();
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) vol;
+
for(int i=0,ni=m_nodes.size();i<ni;++i)
{
Node& n=m_nodes[i];
n.m_x*=scl;
n.m_q*=scl;
- m_ndbvt.update(n.m_leaf,btDbvtVolume::FromCR(n.m_x,margin));
+ vol = btDbvtVolume::FromCR(n.m_x,margin);
+ m_ndbvt.update(n.m_leaf,vol);
}
updateNormals();
updateBounds();
@@ -562,8 +569,8 @@ void btSoftBody::setPose(bool bvolume,bool bframe)
{
Node& n=m_nodes[i];
m_pose.m_wgh[i]= n.m_im>0 ?
- 1/(m_nodes[i].m_im*tmass) :
- kmass/tmass;
+ 1/(m_nodes[i].m_im*tmass) :
+ kmass/tmass;
}
/* Pos */
const btVector3 com=evaluateCom();
@@ -578,16 +585,16 @@ void btSoftBody::setPose(bool bvolume,bool bframe)
m_pose.m_scl.setIdentity();
/* Aqq */
m_pose.m_aqq[0] =
- m_pose.m_aqq[1] =
- m_pose.m_aqq[2] = btVector3(0,0,0);
+ m_pose.m_aqq[1] =
+ m_pose.m_aqq[2] = btVector3(0,0,0);
for( i=0,ni=m_nodes.size();i<ni;++i)
- {
+ {
const btVector3& q=m_pose.m_pos[i];
const btVector3 mq=m_pose.m_wgh[i]*q;
m_pose.m_aqq[0]+=mq.x()*q;
m_pose.m_aqq[1]+=mq.y()*q;
m_pose.m_aqq[2]+=mq.z()*q;
- }
+ }
m_pose.m_aqq=m_pose.m_aqq.inverse();
updateConstants();
}
@@ -614,87 +621,87 @@ btScalar btSoftBody::getVolume() const
//
int btSoftBody::clusterCount() const
{
-return(m_clusters.size());
+ return(m_clusters.size());
}
//
btVector3 btSoftBody::clusterCom(const Cluster* cluster)
{
-btVector3 com(0,0,0);
-for(int i=0,ni=cluster->m_nodes.size();i<ni;++i)
+ btVector3 com(0,0,0);
+ for(int i=0,ni=cluster->m_nodes.size();i<ni;++i)
{
- com+=cluster->m_nodes[i]->m_x*cluster->m_masses[i];
+ com+=cluster->m_nodes[i]->m_x*cluster->m_masses[i];
}
-return(com*cluster->m_imass);
+ return(com*cluster->m_imass);
}
//
btVector3 btSoftBody::clusterCom(int cluster) const
{
-return(clusterCom(m_clusters[cluster]));
+ return(clusterCom(m_clusters[cluster]));
}
//
btVector3 btSoftBody::clusterVelocity(const Cluster* cluster,const btVector3& rpos)
{
-return(cluster->m_lv+cross(cluster->m_av,rpos));
+ return(cluster->m_lv+cross(cluster->m_av,rpos));
}
//
void btSoftBody::clusterVImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse)
{
-const btVector3 li=cluster->m_imass*impulse;
-const btVector3 ai=cluster->m_invwi*cross(rpos,impulse);
-cluster->m_vimpulses[0]+=li;cluster->m_lv+=li;
-cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai;
-cluster->m_nvimpulses++;
+ const btVector3 li=cluster->m_imass*impulse;
+ const btVector3 ai=cluster->m_invwi*cross(rpos,impulse);
+ cluster->m_vimpulses[0]+=li;cluster->m_lv+=li;
+ cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai;
+ cluster->m_nvimpulses++;
}
//
void btSoftBody::clusterDImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse)
{
-const btVector3 li=cluster->m_imass*impulse;
-const btVector3 ai=cluster->m_invwi*cross(rpos,impulse);
-cluster->m_dimpulses[0]+=li;
-cluster->m_dimpulses[1]+=ai;
-cluster->m_ndimpulses++;
+ const btVector3 li=cluster->m_imass*impulse;
+ const btVector3 ai=cluster->m_invwi*cross(rpos,impulse);
+ cluster->m_dimpulses[0]+=li;
+ cluster->m_dimpulses[1]+=ai;
+ cluster->m_ndimpulses++;
}
//
void btSoftBody::clusterImpulse(Cluster* cluster,const btVector3& rpos,const Impulse& impulse)
{
-if(impulse.m_asVelocity) clusterVImpulse(cluster,rpos,impulse.m_velocity);
-if(impulse.m_asDrift) clusterDImpulse(cluster,rpos,impulse.m_drift);
+ if(impulse.m_asVelocity) clusterVImpulse(cluster,rpos,impulse.m_velocity);
+ if(impulse.m_asDrift) clusterDImpulse(cluster,rpos,impulse.m_drift);
}
//
void btSoftBody::clusterVAImpulse(Cluster* cluster,const btVector3& impulse)
{
-const btVector3 ai=cluster->m_invwi*impulse;
-cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai;
-cluster->m_nvimpulses++;
+ const btVector3 ai=cluster->m_invwi*impulse;
+ cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai;
+ cluster->m_nvimpulses++;
}
//
void btSoftBody::clusterDAImpulse(Cluster* cluster,const btVector3& impulse)
{
-const btVector3 ai=cluster->m_invwi*impulse;
-cluster->m_dimpulses[1]+=ai;
-cluster->m_ndimpulses++;
+ const btVector3 ai=cluster->m_invwi*impulse;
+ cluster->m_dimpulses[1]+=ai;
+ cluster->m_ndimpulses++;
}
//
void btSoftBody::clusterAImpulse(Cluster* cluster,const Impulse& impulse)
{
-if(impulse.m_asVelocity) clusterVAImpulse(cluster,impulse.m_velocity);
-if(impulse.m_asDrift) clusterDAImpulse(cluster,impulse.m_drift);
+ if(impulse.m_asVelocity) clusterVAImpulse(cluster,impulse.m_velocity);
+ if(impulse.m_asDrift) clusterDAImpulse(cluster,impulse.m_drift);
}
//
void btSoftBody::clusterDCImpulse(Cluster* cluster,const btVector3& impulse)
{
-cluster->m_dimpulses[0]+=impulse*cluster->m_imass;
-cluster->m_ndimpulses++;
+ cluster->m_dimpulses[0]+=impulse*cluster->m_imass;
+ cluster->m_ndimpulses++;
}
//
@@ -762,9 +769,9 @@ int btSoftBody::generateBendingConstraints(int distance,Material* mat)
//
void btSoftBody::randomizeConstraints()
{
-unsigned long seed=243703;
+ unsigned long seed=243703;
#define NEXTRAND (seed=(1664525L*seed+1013904223L)&0xffffffff)
-int i,ni;
+ int i,ni;
for(i=0,ni=m_links.size();i<ni;++i)
{
@@ -780,493 +787,524 @@ int i,ni;
//
void btSoftBody::releaseCluster(int index)
{
-Cluster* c=m_clusters[index];
-if(c->m_leaf) m_cdbvt.remove(c->m_leaf);
-c->~Cluster();
-btAlignedFree(c);
-m_clusters.remove(c);
+ Cluster* c=m_clusters[index];
+ if(c->m_leaf) m_cdbvt.remove(c->m_leaf);
+ c->~Cluster();
+ btAlignedFree(c);
+ m_clusters.remove(c);
}
//
void btSoftBody::releaseClusters()
{
-while(m_clusters.size()>0) releaseCluster(0);
+ while(m_clusters.size()>0) releaseCluster(0);
}
//
int btSoftBody::generateClusters(int k,int maxiterations)
{
-int i;
-releaseClusters();
-m_clusters.resize(btMin(k,m_nodes.size()));
-for(i=0;i<m_clusters.size();++i)
- {
- m_clusters[i] = new(btAlignedAlloc(sizeof(Cluster),16)) Cluster();
- m_clusters[i]->m_collide= true;
- }
-k=m_clusters.size();
-if(k>0)
- {
- /* Initialize */
- btAlignedObjectArray<btVector3> centers;
- btVector3 cog(0,0,0);
- int i;
- for(i=0;i<m_nodes.size();++i)
- {
- cog+=m_nodes[i].m_x;
- m_clusters[(i*29873)%m_clusters.size()]->m_nodes.push_back(&m_nodes[i]);
- }
- cog/=(btScalar)m_nodes.size();
- centers.resize(k,cog);
- /* Iterate */
- const btScalar slope=16;
- bool changed;
- int iterations=0;
- do {
- const btScalar w=2-btMin<btScalar>(1,iterations/slope);
- changed=false;
- iterations++;
- int i;
-
- for(i=0;i<k;++i)
+ int i;
+ releaseClusters();
+ m_clusters.resize(btMin(k,m_nodes.size()));
+ for(i=0;i<m_clusters.size();++i)
+ {
+ m_clusters[i] = new(btAlignedAlloc(sizeof(Cluster),16)) Cluster();
+ m_clusters[i]->m_collide= true;
+ }
+ k=m_clusters.size();
+ if(k>0)
+ {
+ /* Initialize */
+ btAlignedObjectArray<btVector3> centers;
+ btVector3 cog(0,0,0);
+ int i;
+ for(i=0;i<m_nodes.size();++i)
+ {
+ cog+=m_nodes[i].m_x;
+ m_clusters[(i*29873)%m_clusters.size()]->m_nodes.push_back(&m_nodes[i]);
+ }
+ cog/=(btScalar)m_nodes.size();
+ centers.resize(k,cog);
+ /* Iterate */
+ const btScalar slope=16;
+ bool changed;
+ int iterations=0;
+ do {
+ const btScalar w=2-btMin<btScalar>(1,iterations/slope);
+ changed=false;
+ iterations++;
+ int i;
+
+ for(i=0;i<k;++i)
{
- btVector3 c(0,0,0);
- for(int j=0;j<m_clusters[i]->m_nodes.size();++j)
+ btVector3 c(0,0,0);
+ for(int j=0;j<m_clusters[i]->m_nodes.size();++j)
{
- c+=m_clusters[i]->m_nodes[j]->m_x;
+ c+=m_clusters[i]->m_nodes[j]->m_x;
}
- if(m_clusters[i]->m_nodes.size())
+ if(m_clusters[i]->m_nodes.size())
{
- c /= (btScalar)m_clusters[i]->m_nodes.size();
- c = centers[i]+(c-centers[i])*w;
- changed |= ((c-centers[i]).length2()>SIMD_EPSILON);
- centers[i] = c;
- m_clusters[i]->m_nodes.resize(0);
+ c /= (btScalar)m_clusters[i]->m_nodes.size();
+ c = centers[i]+(c-centers[i])*w;
+ changed |= ((c-centers[i]).length2()>SIMD_EPSILON);
+ centers[i] = c;
+ m_clusters[i]->m_nodes.resize(0);
}
}
- for(i=0;i<m_nodes.size();++i)
+ for(i=0;i<m_nodes.size();++i)
{
- const btVector3 nx=m_nodes[i].m_x;
- int kbest=0;
- btScalar kdist=ClusterMetric(centers[0],nx);
- for(int j=1;j<k;++j)
+ const btVector3 nx=m_nodes[i].m_x;
+ int kbest=0;
+ btScalar kdist=ClusterMetric(centers[0],nx);
+ for(int j=1;j<k;++j)
{
- const btScalar d=ClusterMetric(centers[j],nx);
- if(d<kdist)
+ const btScalar d=ClusterMetric(centers[j],nx);
+ if(d<kdist)
{
- kbest=j;
- kdist=d;
+ kbest=j;
+ kdist=d;
}
}
- m_clusters[kbest]->m_nodes.push_back(&m_nodes[i]);
+ m_clusters[kbest]->m_nodes.push_back(&m_nodes[i]);
}
} while(changed&&(iterations<maxiterations));
- /* Merge */
- btAlignedObjectArray<int> cids;
- cids.resize(m_nodes.size(),-1);
- for(i=0;i<m_clusters.size();++i)
+ /* Merge */
+ btAlignedObjectArray<int> cids;
+ cids.resize(m_nodes.size(),-1);
+ for(i=0;i<m_clusters.size();++i)
{
- for(int j=0;j<m_clusters[i]->m_nodes.size();++j)
+ for(int j=0;j<m_clusters[i]->m_nodes.size();++j)
{
- cids[int(m_clusters[i]->m_nodes[j]-&m_nodes[0])]=i;
+ cids[int(m_clusters[i]->m_nodes[j]-&m_nodes[0])]=i;
}
}
- for(i=0;i<m_faces.size();++i)
+ for(i=0;i<m_faces.size();++i)
{
- const int idx[]={ int(m_faces[i].m_n[0]-&m_nodes[0]),
- int(m_faces[i].m_n[1]-&m_nodes[0]),
- int(m_faces[i].m_n[2]-&m_nodes[0])};
- for(int j=0;j<3;++j)
+ const int idx[]={ int(m_faces[i].m_n[0]-&m_nodes[0]),
+ int(m_faces[i].m_n[1]-&m_nodes[0]),
+ int(m_faces[i].m_n[2]-&m_nodes[0])};
+ for(int j=0;j<3;++j)
{
- const int cid=cids[idx[j]];
- for(int q=1;q<3;++q)
+ const int cid=cids[idx[j]];
+ for(int q=1;q<3;++q)
{
- const int kid=idx[(j+q)%3];
- if(cids[kid]!=cid)
+ const int kid=idx[(j+q)%3];
+ if(cids[kid]!=cid)
{
- if(m_clusters[cid]->m_nodes.findLinearSearch(&m_nodes[kid])==m_clusters[cid]->m_nodes.size())
+ if(m_clusters[cid]->m_nodes.findLinearSearch(&m_nodes[kid])==m_clusters[cid]->m_nodes.size())
{
- m_clusters[cid]->m_nodes.push_back(&m_nodes[kid]);
+ m_clusters[cid]->m_nodes.push_back(&m_nodes[kid]);
}
}
}
}
}
- /* Master */
- if(m_clusters.size()>1)
+ /* Master */
+ if(m_clusters.size()>1)
{
- Cluster* pmaster=new(btAlignedAlloc(sizeof(Cluster),16)) Cluster();
- pmaster->m_collide = false;
- pmaster->m_nodes.reserve(m_nodes.size());
- for(int i=0;i<m_nodes.size();++i) pmaster->m_nodes.push_back(&m_nodes[i]);
- m_clusters.push_back(pmaster);
- btSwap(m_clusters[0],m_clusters[m_clusters.size()-1]);
+ Cluster* pmaster=new(btAlignedAlloc(sizeof(Cluster),16)) Cluster();
+ pmaster->m_collide = false;
+ pmaster->m_nodes.reserve(m_nodes.size());
+ for(int i=0;i<m_nodes.size();++i) pmaster->m_nodes.push_back(&m_nodes[i]);
+ m_clusters.push_back(pmaster);
+ btSwap(m_clusters[0],m_clusters[m_clusters.size()-1]);
}
- /* Terminate */
- for(i=0;i<m_clusters.size();++i)
+ /* Terminate */
+ for(i=0;i<m_clusters.size();++i)
{
- if(m_clusters[i]->m_nodes.size()==0)
+ if(m_clusters[i]->m_nodes.size()==0)
{
- releaseCluster(i--);
+ releaseCluster(i--);
}
}
-
- initializeClusters();
- updateClusters();
- return(m_clusters.size());
+
+ initializeClusters();
+ updateClusters();
+
+ //for self-collision
+ m_clusterConnectivity.resize(m_clusters.size()*m_clusters.size());
+ {
+ for (int c0=0;c0<m_clusters.size();c0++)
+ {
+ m_clusters[c0]->m_clusterIndex=c0;
+ for (int c1=0;c1<m_clusters.size();c1++)
+ {
+
+ bool connected=false;
+ Cluster* cla = m_clusters[c0];
+ Cluster* clb = m_clusters[c1];
+ for (int i=0;!connected&&i<cla->m_nodes.size();i++)
+ {
+ for (int j=0;j<clb->m_nodes.size();j++)
+ {
+ if (cla->m_nodes[i] == clb->m_nodes[j])
+ {
+ connected=true;
+ break;
+ }
+ }
+ }
+ m_clusterConnectivity[c0+c1*m_clusters.size()]=connected;
+ }
+ }
+ }
+
+ return(m_clusters.size());
}
-return(0);
+ return(0);
}
//
void btSoftBody::refine(ImplicitFn* ifn,btScalar accurary,bool cut)
{
-const Node* nbase = &m_nodes[0];
-int ncount = m_nodes.size();
-btSymMatrix<int> edges(ncount,-2);
-int newnodes=0;
-int i,j,k,ni;
+ const Node* nbase = &m_nodes[0];
+ int ncount = m_nodes.size();
+ btSymMatrix<int> edges(ncount,-2);
+ int newnodes=0;
+ int i,j,k,ni;
-/* Filter out */
-for(i=0;i<m_links.size();++i)
+ /* Filter out */
+ for(i=0;i<m_links.size();++i)
{
- Link& l=m_links[i];
- if(l.m_bbending)
+ Link& l=m_links[i];
+ if(l.m_bbending)
{
- if(!SameSign(ifn->Eval(l.m_n[0]->m_x),ifn->Eval(l.m_n[1]->m_x)))
+ if(!SameSign(ifn->Eval(l.m_n[0]->m_x),ifn->Eval(l.m_n[1]->m_x)))
{
- btSwap(m_links[i],m_links[m_links.size()-1]);
- m_links.pop_back();--i;
+ btSwap(m_links[i],m_links[m_links.size()-1]);
+ m_links.pop_back();--i;
}
}
}
-/* Fill edges */
-for(i=0;i<m_links.size();++i)
+ /* Fill edges */
+ for(i=0;i<m_links.size();++i)
{
- Link& l=m_links[i];
- edges(int(l.m_n[0]-nbase),int(l.m_n[1]-nbase))=-1;
+ Link& l=m_links[i];
+ edges(int(l.m_n[0]-nbase),int(l.m_n[1]-nbase))=-1;
}
-for(i=0;i<m_faces.size();++i)
+ for(i=0;i<m_faces.size();++i)
{
- Face& f=m_faces[i];
- edges(int(f.m_n[0]-nbase),int(f.m_n[1]-nbase))=-1;
- edges(int(f.m_n[1]-nbase),int(f.m_n[2]-nbase))=-1;
- edges(int(f.m_n[2]-nbase),int(f.m_n[0]-nbase))=-1;
+ Face& f=m_faces[i];
+ edges(int(f.m_n[0]-nbase),int(f.m_n[1]-nbase))=-1;
+ edges(int(f.m_n[1]-nbase),int(f.m_n[2]-nbase))=-1;
+ edges(int(f.m_n[2]-nbase),int(f.m_n[0]-nbase))=-1;
}
-/* Intersect */
-for(i=0;i<ncount;++i)
+ /* Intersect */
+ for(i=0;i<ncount;++i)
{
- for(j=i+1;j<ncount;++j)
+ for(j=i+1;j<ncount;++j)
{
- if(edges(i,j)==-1)
+ if(edges(i,j)==-1)
{
- Node& a=m_nodes[i];
- Node& b=m_nodes[j];
- const btScalar t=ImplicitSolve(ifn,a.m_x,b.m_x,accurary);
- if(t>0)
+ Node& a=m_nodes[i];
+ Node& b=m_nodes[j];
+ const btScalar t=ImplicitSolve(ifn,a.m_x,b.m_x,accurary);
+ if(t>0)
{
- const btVector3 x=Lerp(a.m_x,b.m_x,t);
- const btVector3 v=Lerp(a.m_v,b.m_v,t);
- btScalar m=0;
- if(a.m_im>0)
+ const btVector3 x=Lerp(a.m_x,b.m_x,t);
+ const btVector3 v=Lerp(a.m_v,b.m_v,t);
+ btScalar m=0;
+ if(a.m_im>0)
{
- if(b.m_im>0)
+ if(b.m_im>0)
{
- const btScalar ma=1/a.m_im;
- const btScalar mb=1/b.m_im;
- const btScalar mc=Lerp(ma,mb,t);
- const btScalar f=(ma+mb)/(ma+mb+mc);
- a.m_im=1/(ma*f);
- b.m_im=1/(mb*f);
- m=mc*f;
+ const btScalar ma=1/a.m_im;
+ const btScalar mb=1/b.m_im;
+ const btScalar mc=Lerp(ma,mb,t);
+ const btScalar f=(ma+mb)/(ma+mb+mc);
+ a.m_im=1/(ma*f);
+ b.m_im=1/(mb*f);
+ m=mc*f;
}
else
{ a.m_im/=0.5;m=1/a.m_im; }
}
else
{
- if(b.m_im>0)
+ if(b.m_im>0)
{ b.m_im/=0.5;m=1/b.m_im; }
else
- m=0;
+ m=0;
}
- appendNode(x,m);
- edges(i,j)=m_nodes.size()-1;
- m_nodes[edges(i,j)].m_v=v;
- ++newnodes;
+ appendNode(x,m);
+ edges(i,j)=m_nodes.size()-1;
+ m_nodes[edges(i,j)].m_v=v;
+ ++newnodes;
}
}
}
}
-nbase=&m_nodes[0];
-/* Refine links */
-for(i=0,ni=m_links.size();i<ni;++i)
+ nbase=&m_nodes[0];
+ /* Refine links */
+ for(i=0,ni=m_links.size();i<ni;++i)
{
- Link& feat=m_links[i];
- const int idx[]={ int(feat.m_n[0]-nbase),
- int(feat.m_n[1]-nbase)};
- if((idx[0]<ncount)&&(idx[1]<ncount))
+ Link& feat=m_links[i];
+ const int idx[]={ int(feat.m_n[0]-nbase),
+ int(feat.m_n[1]-nbase)};
+ if((idx[0]<ncount)&&(idx[1]<ncount))
{
- const int ni=edges(idx[0],idx[1]);
- if(ni>0)
+ const int ni=edges(idx[0],idx[1]);
+ if(ni>0)
{
- appendLink(i);
- Link* pft[]={ &m_links[i],
- &m_links[m_links.size()-1]};
- pft[0]->m_n[0]=&m_nodes[idx[0]];
- pft[0]->m_n[1]=&m_nodes[ni];
- pft[1]->m_n[0]=&m_nodes[ni];
- pft[1]->m_n[1]=&m_nodes[idx[1]];
+ appendLink(i);
+ Link* pft[]={ &m_links[i],
+ &m_links[m_links.size()-1]};
+ pft[0]->m_n[0]=&m_nodes[idx[0]];
+ pft[0]->m_n[1]=&m_nodes[ni];
+ pft[1]->m_n[0]=&m_nodes[ni];
+ pft[1]->m_n[1]=&m_nodes[idx[1]];
}
}
}
-/* Refine faces */
-for(i=0;i<m_faces.size();++i)
+ /* Refine faces */
+ for(i=0;i<m_faces.size();++i)
{
- const Face& feat=m_faces[i];
- const int idx[]={ int(feat.m_n[0]-nbase),
- int(feat.m_n[1]-nbase),
- int(feat.m_n[2]-nbase)};
- for(j=2,k=0;k<3;j=k++)
+ const Face& feat=m_faces[i];
+ const int idx[]={ int(feat.m_n[0]-nbase),
+ int(feat.m_n[1]-nbase),
+ int(feat.m_n[2]-nbase)};
+ for(j=2,k=0;k<3;j=k++)
{
- if((idx[j]<ncount)&&(idx[k]<ncount))
+ if((idx[j]<ncount)&&(idx[k]<ncount))
{
- const int ni=edges(idx[j],idx[k]);
- if(ni>0)
+ const int ni=edges(idx[j],idx[k]);
+ if(ni>0)
{
- appendFace(i);
- const int l=(k+1)%3;
- Face* pft[]={ &m_faces[i],
- &m_faces[m_faces.size()-1]};
- pft[0]->m_n[0]=&m_nodes[idx[l]];
- pft[0]->m_n[1]=&m_nodes[idx[j]];
- pft[0]->m_n[2]=&m_nodes[ni];
- pft[1]->m_n[0]=&m_nodes[ni];
- pft[1]->m_n[1]=&m_nodes[idx[k]];
- pft[1]->m_n[2]=&m_nodes[idx[l]];
- appendLink(ni,idx[l],pft[0]->m_material);
- --i;break;
+ appendFace(i);
+ const int l=(k+1)%3;
+ Face* pft[]={ &m_faces[i],
+ &m_faces[m_faces.size()-1]};
+ pft[0]->m_n[0]=&m_nodes[idx[l]];
+ pft[0]->m_n[1]=&m_nodes[idx[j]];
+ pft[0]->m_n[2]=&m_nodes[ni];
+ pft[1]->m_n[0]=&m_nodes[ni];
+ pft[1]->m_n[1]=&m_nodes[idx[k]];
+ pft[1]->m_n[2]=&m_nodes[idx[l]];
+ appendLink(ni,idx[l],pft[0]->m_material);
+ --i;break;
}
}
}
}
-/* Cut */
-if(cut)
+ /* Cut */
+ if(cut)
{
- btAlignedObjectArray<int> cnodes;
- const int pcount=ncount;
- int i;
- ncount=m_nodes.size();
- cnodes.resize(ncount,0);
- /* Nodes */
- for(i=0;i<ncount;++i)
- {
- const btVector3 x=m_nodes[i].m_x;
- if((i>=pcount)||(btFabs(ifn->Eval(x))<accurary))
+ btAlignedObjectArray<int> cnodes;
+ const int pcount=ncount;
+ int i;
+ ncount=m_nodes.size();
+ cnodes.resize(ncount,0);
+ /* Nodes */
+ for(i=0;i<ncount;++i)
+ {
+ const btVector3 x=m_nodes[i].m_x;
+ if((i>=pcount)||(btFabs(ifn->Eval(x))<accurary))
{
- const btVector3 v=m_nodes[i].m_v;
- btScalar m=getMass(i);
- if(m>0) { m*=0.5;m_nodes[i].m_im/=0.5; }
- appendNode(x,m);
- cnodes[i]=m_nodes.size()-1;
- m_nodes[cnodes[i]].m_v=v;
+ const btVector3 v=m_nodes[i].m_v;
+ btScalar m=getMass(i);
+ if(m>0) { m*=0.5;m_nodes[i].m_im/=0.5; }
+ appendNode(x,m);
+ cnodes[i]=m_nodes.size()-1;
+ m_nodes[cnodes[i]].m_v=v;
}
}
- nbase=&m_nodes[0];
- /* Links */
- for(i=0,ni=m_links.size();i<ni;++i)
+ nbase=&m_nodes[0];
+ /* Links */
+ for(i=0,ni=m_links.size();i<ni;++i)
{
- const int id[]={ int(m_links[i].m_n[0]-nbase),
- int(m_links[i].m_n[1]-nbase)};
- int todetach=0;
- if(cnodes[id[0]]&&cnodes[id[1]])
+ const int id[]={ int(m_links[i].m_n[0]-nbase),
+ int(m_links[i].m_n[1]-nbase)};
+ int todetach=0;
+ if(cnodes[id[0]]&&cnodes[id[1]])
{
- appendLink(i);
- todetach=m_links.size()-1;
+ appendLink(i);
+ todetach=m_links.size()-1;
}
- else
+ else
{
- if(( (ifn->Eval(m_nodes[id[0]].m_x)<accurary)&&
+ if(( (ifn->Eval(m_nodes[id[0]].m_x)<accurary)&&
(ifn->Eval(m_nodes[id[1]].m_x)<accurary)))
- todetach=i;
+ todetach=i;
}
- if(todetach)
+ if(todetach)
{
- Link& l=m_links[todetach];
- for(int j=0;j<2;++j)
+ Link& l=m_links[todetach];
+ for(int j=0;j<2;++j)
{
- int cn=cnodes[int(l.m_n[j]-nbase)];
- if(cn) l.m_n[j]=&m_nodes[cn];
+ int cn=cnodes[int(l.m_n[j]-nbase)];
+ if(cn) l.m_n[j]=&m_nodes[cn];
}
}
}
- /* Faces */
- for(i=0,ni=m_faces.size();i<ni;++i)
+ /* Faces */
+ for(i=0,ni=m_faces.size();i<ni;++i)
{
- Node** n= m_faces[i].m_n;
- if( (ifn->Eval(n[0]->m_x)<accurary)&&
- (ifn->Eval(n[1]->m_x)<accurary)&&
- (ifn->Eval(n[2]->m_x)<accurary))
+ Node** n= m_faces[i].m_n;
+ if( (ifn->Eval(n[0]->m_x)<accurary)&&
+ (ifn->Eval(n[1]->m_x)<accurary)&&
+ (ifn->Eval(n[2]->m_x)<accurary))
{
- for(int j=0;j<3;++j)
+ for(int j=0;j<3;++j)
{
- int cn=cnodes[int(n[j]-nbase)];
- if(cn) n[j]=&m_nodes[cn];
+ int cn=cnodes[int(n[j]-nbase)];
+ if(cn) n[j]=&m_nodes[cn];
}
}
}
- /* Clean orphans */
- int nnodes=m_nodes.size();
- btAlignedObjectArray<int> ranks;
- btAlignedObjectArray<int> todelete;
- ranks.resize(nnodes,0);
- for(i=0,ni=m_links.size();i<ni;++i)
+ /* Clean orphans */
+ int nnodes=m_nodes.size();
+ btAlignedObjectArray<int> ranks;
+ btAlignedObjectArray<int> todelete;
+ ranks.resize(nnodes,0);
+ for(i=0,ni=m_links.size();i<ni;++i)
{
- for(int j=0;j<2;++j) ranks[int(m_links[i].m_n[j]-nbase)]++;
+ for(int j=0;j<2;++j) ranks[int(m_links[i].m_n[j]-nbase)]++;
}
- for(i=0,ni=m_faces.size();i<ni;++i)
+ for(i=0,ni=m_faces.size();i<ni;++i)
{
- for(int j=0;j<3;++j) ranks[int(m_faces[i].m_n[j]-nbase)]++;
+ for(int j=0;j<3;++j) ranks[int(m_faces[i].m_n[j]-nbase)]++;
}
- for(i=0;i<m_links.size();++i)
+ for(i=0;i<m_links.size();++i)
{
- const int id[]={ int(m_links[i].m_n[0]-nbase),
- int(m_links[i].m_n[1]-nbase)};
- const bool sg[]={ ranks[id[0]]==1,
- ranks[id[1]]==1};
- if(sg[0]||sg[1])
+ const int id[]={ int(m_links[i].m_n[0]-nbase),
+ int(m_links[i].m_n[1]-nbase)};
+ const bool sg[]={ ranks[id[0]]==1,
+ ranks[id[1]]==1};
+ if(sg[0]||sg[1])
{
- --ranks[id[0]];
- --ranks[id[1]];
- btSwap(m_links[i],m_links[m_links.size()-1]);
- m_links.pop_back();--i;
+ --ranks[id[0]];
+ --ranks[id[1]];
+ btSwap(m_links[i],m_links[m_links.size()-1]);
+ m_links.pop_back();--i;
}
}
- #if 0
- for(i=nnodes-1;i>=0;--i)
+#if 0
+ for(i=nnodes-1;i>=0;--i)
{
- if(!ranks[i]) todelete.push_back(i);
+ if(!ranks[i]) todelete.push_back(i);
}
- if(todelete.size())
+ if(todelete.size())
{
- btAlignedObjectArray<int>& map=ranks;
- for(int i=0;i<nnodes;++i) map[i]=i;
- PointersToIndices(this);
- for(int i=0,ni=todelete.size();i<ni;++i)
+ btAlignedObjectArray<int>& map=ranks;
+ for(int i=0;i<nnodes;++i) map[i]=i;
+ PointersToIndices(this);
+ for(int i=0,ni=todelete.size();i<ni;++i)
{
- int j=todelete[i];
- int& a=map[j];
- int& b=map[--nnodes];
- m_ndbvt.remove(m_nodes[a].m_leaf);m_nodes[a].m_leaf=0;
- btSwap(m_nodes[a],m_nodes[b]);
- j=a;a=b;b=j;
+ int j=todelete[i];
+ int& a=map[j];
+ int& b=map[--nnodes];
+ m_ndbvt.remove(m_nodes[a].m_leaf);m_nodes[a].m_leaf=0;
+ btSwap(m_nodes[a],m_nodes[b]);
+ j=a;a=b;b=j;
}
- IndicesToPointers(this,&map[0]);
- m_nodes.resize(nnodes);
+ IndicesToPointers(this,&map[0]);
+ m_nodes.resize(nnodes);
}
- #endif
+#endif
}
-m_bUpdateRtCst=true;
+ m_bUpdateRtCst=true;
}
//
bool btSoftBody::cutLink(const Node* node0,const Node* node1,btScalar position)
{
-return(cutLink(int(node0-&m_nodes[0]),int(node1-&m_nodes[0]),position));
+ return(cutLink(int(node0-&m_nodes[0]),int(node1-&m_nodes[0]),position));
}
//
bool btSoftBody::cutLink(int node0,int node1,btScalar position)
{
-bool done=false;
-int i,ni;
-const btVector3 d=m_nodes[node0].m_x-m_nodes[node1].m_x;
-const btVector3 x=Lerp(m_nodes[node0].m_x,m_nodes[node1].m_x,position);
-const btVector3 v=Lerp(m_nodes[node0].m_v,m_nodes[node1].m_v,position);
-const btScalar m=1;
-appendNode(x,m);
-appendNode(x,m);
-Node* pa=&m_nodes[node0];
-Node* pb=&m_nodes[node1];
-Node* pn[2]={ &m_nodes[m_nodes.size()-2],
- &m_nodes[m_nodes.size()-1]};
-pn[0]->m_v=v;
-pn[1]->m_v=v;
-for(i=0,ni=m_links.size();i<ni;++i)
- {
- const int mtch=MatchEdge(m_links[i].m_n[0],m_links[i].m_n[1],pa,pb);
- if(mtch!=-1)
- {
- appendLink(i);
- Link* pft[]={&m_links[i],&m_links[m_links.size()-1]};
- pft[0]->m_n[1]=pn[mtch];
- pft[1]->m_n[0]=pn[1-mtch];
- done=true;
- }
- }
-for(i=0,ni=m_faces.size();i<ni;++i)
- {
- for(int k=2,l=0;l<3;k=l++)
- {
- const int mtch=MatchEdge(m_faces[i].m_n[k],m_faces[i].m_n[l],pa,pb);
+ bool done=false;
+ int i,ni;
+ const btVector3 d=m_nodes[node0].m_x-m_nodes[node1].m_x;
+ const btVector3 x=Lerp(m_nodes[node0].m_x,m_nodes[node1].m_x,position);
+ const btVector3 v=Lerp(m_nodes[node0].m_v,m_nodes[node1].m_v,position);
+ const btScalar m=1;
+ appendNode(x,m);
+ appendNode(x,m);
+ Node* pa=&m_nodes[node0];
+ Node* pb=&m_nodes[node1];
+ Node* pn[2]={ &m_nodes[m_nodes.size()-2],
+ &m_nodes[m_nodes.size()-1]};
+ pn[0]->m_v=v;
+ pn[1]->m_v=v;
+ for(i=0,ni=m_links.size();i<ni;++i)
+ {
+ const int mtch=MatchEdge(m_links[i].m_n[0],m_links[i].m_n[1],pa,pb);
if(mtch!=-1)
+ {
+ appendLink(i);
+ Link* pft[]={&m_links[i],&m_links[m_links.size()-1]};
+ pft[0]->m_n[1]=pn[mtch];
+ pft[1]->m_n[0]=pn[1-mtch];
+ done=true;
+ }
+ }
+ for(i=0,ni=m_faces.size();i<ni;++i)
+ {
+ for(int k=2,l=0;l<3;k=l++)
+ {
+ const int mtch=MatchEdge(m_faces[i].m_n[k],m_faces[i].m_n[l],pa,pb);
+ if(mtch!=-1)
{
- appendFace(i);
- Face* pft[]={&m_faces[i],&m_faces[m_faces.size()-1]};
- pft[0]->m_n[l]=pn[mtch];
- pft[1]->m_n[k]=pn[1-mtch];
- appendLink(pn[0],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true);
- appendLink(pn[1],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true);
+ appendFace(i);
+ Face* pft[]={&m_faces[i],&m_faces[m_faces.size()-1]};
+ pft[0]->m_n[l]=pn[mtch];
+ pft[1]->m_n[k]=pn[1-mtch];
+ appendLink(pn[0],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true);
+ appendLink(pn[1],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true);
}
}
}
-if(!done)
+ if(!done)
{
- m_ndbvt.remove(pn[0]->m_leaf);
- m_ndbvt.remove(pn[1]->m_leaf);
- m_nodes.pop_back();
- m_nodes.pop_back();
+ m_ndbvt.remove(pn[0]->m_leaf);
+ m_ndbvt.remove(pn[1]->m_leaf);
+ m_nodes.pop_back();
+ m_nodes.pop_back();
}
-return(done);
+ return(done);
}
//
-bool btSoftBody::rayCast(const btVector3& org,
- const btVector3& dir,
- sRayCast& results,
- btScalar maxtime)
+bool btSoftBody::rayTest(const btVector3& rayFrom,
+ const btVector3& rayTo,
+ sRayCast& results)
{
-if(m_faces.size()&&m_fdbvt.empty()) initializeFaceTree();
-results.body = this;
-results.time = maxtime;
-results.feature = eFeature::None;
-results.index = -1;
-return(rayCast(org,dir,results.time,results.feature,results.index,false)!=0);
+ if(m_faces.size()&&m_fdbvt.empty())
+ initializeFaceTree();
+
+ results.body = this;
+ results.fraction = 1.f;
+ results.feature = eFeature::None;
+ results.index = -1;
+
+ return(rayTest(rayFrom,rayTo,results.fraction,results.feature,results.index,false)!=0);
}
//
void btSoftBody::setSolver(eSolverPresets::_ preset)
{
-m_cfg.m_vsequence.clear();
-m_cfg.m_psequence.clear();
-m_cfg.m_dsequence.clear();
-switch(preset)
+ m_cfg.m_vsequence.clear();
+ m_cfg.m_psequence.clear();
+ m_cfg.m_dsequence.clear();
+ switch(preset)
{
case eSolverPresets::Positions:
- m_cfg.m_psequence.push_back(ePSolver::Anchors);
- m_cfg.m_psequence.push_back(ePSolver::RContacts);
- m_cfg.m_psequence.push_back(ePSolver::SContacts);
- m_cfg.m_psequence.push_back(ePSolver::Linear);
- break;
+ m_cfg.m_psequence.push_back(ePSolver::Anchors);
+ m_cfg.m_psequence.push_back(ePSolver::RContacts);
+ m_cfg.m_psequence.push_back(ePSolver::SContacts);
+ m_cfg.m_psequence.push_back(ePSolver::Linear);
+ break;
case eSolverPresets::Velocities:
- m_cfg.m_vsequence.push_back(eVSolver::Linear);
-
- m_cfg.m_psequence.push_back(ePSolver::Anchors);
- m_cfg.m_psequence.push_back(ePSolver::RContacts);
- m_cfg.m_psequence.push_back(ePSolver::SContacts);
-
- m_cfg.m_dsequence.push_back(ePSolver::Linear);
- break;
+ m_cfg.m_vsequence.push_back(eVSolver::Linear);
+
+ m_cfg.m_psequence.push_back(ePSolver::Anchors);
+ m_cfg.m_psequence.push_back(ePSolver::RContacts);
+ m_cfg.m_psequence.push_back(ePSolver::SContacts);
+
+ m_cfg.m_dsequence.push_back(ePSolver::Linear);
+ break;
}
}
@@ -1282,11 +1320,11 @@ void btSoftBody::predictMotion(btScalar dt)
updateConstants();
m_fdbvt.clear();
if(m_cfg.collisions&fCollision::VF_SS)
- {
+ {
initializeFaceTree();
- }
+ }
}
-
+
/* Prepare */
m_sst.sdt = dt*m_cfg.timescale;
m_sst.isdt = 1/m_sst.sdt;
@@ -1310,45 +1348,48 @@ void btSoftBody::predictMotion(btScalar dt)
/* Bounds */
updateBounds();
/* Nodes */
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) vol;
for(i=0,ni=m_nodes.size();i<ni;++i)
{
Node& n=m_nodes[i];
+ vol = btDbvtVolume::FromCR(n.m_x,m_sst.radmrg);
m_ndbvt.update( n.m_leaf,
- btDbvtVolume::FromCR(n.m_x,m_sst.radmrg),
- n.m_v*m_sst.velmrg,
- m_sst.updmrg);
+ vol,
+ n.m_v*m_sst.velmrg,
+ m_sst.updmrg);
}
/* Faces */
if(!m_fdbvt.empty())
- {
+ {
for(int i=0;i<m_faces.size();++i)
- {
+ {
Face& f=m_faces[i];
const btVector3 v=( f.m_n[0]->m_v+
- f.m_n[1]->m_v+
- f.m_n[2]->m_v)/3;
+ f.m_n[1]->m_v+
+ f.m_n[2]->m_v)/3;
+ vol = VolumeOf(f,m_sst.radmrg);
m_fdbvt.update( f.m_leaf,
- VolumeOf(f,m_sst.radmrg),
- v*m_sst.velmrg,
- m_sst.updmrg);
- }
+ vol,
+ v*m_sst.velmrg,
+ m_sst.updmrg);
}
+ }
/* Pose */
updatePose();
/* Match */
if(m_pose.m_bframe&&(m_cfg.kMT>0))
- {
+ {
const btMatrix3x3 posetrs=m_pose.m_rot;
for(int i=0,ni=m_nodes.size();i<ni;++i)
- {
+ {
Node& n=m_nodes[i];
if(n.m_im>0)
- {
+ {
const btVector3 x=posetrs*m_pose.m_pos[i]+m_pose.m_com;
n.m_x=Lerp(n.m_x,x,m_cfg.kMT);
- }
}
}
+ }
/* Clear contacts */
m_rcontacts.resize(0);
m_scontacts.resize(0);
@@ -1361,104 +1402,104 @@ void btSoftBody::predictMotion(btScalar dt)
//
void btSoftBody::solveConstraints()
{
-/* Apply clusters */
-applyClusters(false);
-/* Prepare links */
+ /* Apply clusters */
+ applyClusters(false);
+ /* Prepare links */
-int i,ni;
+ int i,ni;
-for(i=0,ni=m_links.size();i<ni;++i)
+ for(i=0,ni=m_links.size();i<ni;++i)
{
- Link& l=m_links[i];
- l.m_c3 = l.m_n[1]->m_q-l.m_n[0]->m_q;
- l.m_c2 = 1/(l.m_c3.length2()*l.m_c0);
+ Link& l=m_links[i];
+ l.m_c3 = l.m_n[1]->m_q-l.m_n[0]->m_q;
+ l.m_c2 = 1/(l.m_c3.length2()*l.m_c0);
}
-/* Prepare anchors */
-for(i=0,ni=m_anchors.size();i<ni;++i)
+ /* Prepare anchors */
+ for(i=0,ni=m_anchors.size();i<ni;++i)
{
- Anchor& a=m_anchors[i];
- const btVector3 ra=a.m_body->getWorldTransform().getBasis()*a.m_local;
- a.m_c0 = ImpulseMatrix( m_sst.sdt,
- a.m_node->m_im,
- a.m_body->getInvMass(),
- a.m_body->getInvInertiaTensorWorld(),
- ra);
- a.m_c1 = ra;
- a.m_c2 = m_sst.sdt*a.m_node->m_im;
- a.m_body->activate();
+ Anchor& a=m_anchors[i];
+ const btVector3 ra=a.m_body->getWorldTransform().getBasis()*a.m_local;
+ a.m_c0 = ImpulseMatrix( m_sst.sdt,
+ a.m_node->m_im,
+ a.m_body->getInvMass(),
+ a.m_body->getInvInertiaTensorWorld(),
+ ra);
+ a.m_c1 = ra;
+ a.m_c2 = m_sst.sdt*a.m_node->m_im;
+ a.m_body->activate();
}
-/* Solve velocities */
-if(m_cfg.viterations>0)
+ /* Solve velocities */
+ if(m_cfg.viterations>0)
{
- /* Solve */
- for(int isolve=0;isolve<m_cfg.viterations;++isolve)
+ /* Solve */
+ for(int isolve=0;isolve<m_cfg.viterations;++isolve)
{
- for(int iseq=0;iseq<m_cfg.m_vsequence.size();++iseq)
+ for(int iseq=0;iseq<m_cfg.m_vsequence.size();++iseq)
{
- getSolver(m_cfg.m_vsequence[iseq])(this,1);
+ getSolver(m_cfg.m_vsequence[iseq])(this,1);
}
}
- /* Update */
- for(i=0,ni=m_nodes.size();i<ni;++i)
+ /* Update */
+ for(i=0,ni=m_nodes.size();i<ni;++i)
{
- Node& n=m_nodes[i];
- n.m_x = n.m_q+n.m_v*m_sst.sdt;
+ Node& n=m_nodes[i];
+ n.m_x = n.m_q+n.m_v*m_sst.sdt;
}
}
-/* Solve positions */
-if(m_cfg.piterations>0)
+ /* Solve positions */
+ if(m_cfg.piterations>0)
{
- for(int isolve=0;isolve<m_cfg.piterations;++isolve)
+ for(int isolve=0;isolve<m_cfg.piterations;++isolve)
{
- const btScalar ti=isolve/(btScalar)m_cfg.piterations;
- for(int iseq=0;iseq<m_cfg.m_psequence.size();++iseq)
+ const btScalar ti=isolve/(btScalar)m_cfg.piterations;
+ for(int iseq=0;iseq<m_cfg.m_psequence.size();++iseq)
{
- getSolver(m_cfg.m_psequence[iseq])(this,1,ti);
+ getSolver(m_cfg.m_psequence[iseq])(this,1,ti);
}
}
- const btScalar vc=m_sst.isdt*(1-m_cfg.kDP);
- for(i=0,ni=m_nodes.size();i<ni;++i)
+ const btScalar vc=m_sst.isdt*(1-m_cfg.kDP);
+ for(i=0,ni=m_nodes.size();i<ni;++i)
{
- Node& n=m_nodes[i];
- n.m_v = (n.m_x-n.m_q)*vc;
- n.m_f = btVector3(0,0,0);
+ Node& n=m_nodes[i];
+ n.m_v = (n.m_x-n.m_q)*vc;
+ n.m_f = btVector3(0,0,0);
}
}
-/* Solve drift */
-if(m_cfg.diterations>0)
+ /* Solve drift */
+ if(m_cfg.diterations>0)
{
- const btScalar vcf=m_cfg.kVCF*m_sst.isdt;
- for(i=0,ni=m_nodes.size();i<ni;++i)
+ const btScalar vcf=m_cfg.kVCF*m_sst.isdt;
+ for(i=0,ni=m_nodes.size();i<ni;++i)
{
- Node& n=m_nodes[i];
- n.m_q = n.m_x;
+ Node& n=m_nodes[i];
+ n.m_q = n.m_x;
}
- for(int idrift=0;idrift<m_cfg.diterations;++idrift)
+ for(int idrift=0;idrift<m_cfg.diterations;++idrift)
{
- for(int iseq=0;iseq<m_cfg.m_dsequence.size();++iseq)
+ for(int iseq=0;iseq<m_cfg.m_dsequence.size();++iseq)
{
- getSolver(m_cfg.m_dsequence[iseq])(this,1,0);
+ getSolver(m_cfg.m_dsequence[iseq])(this,1,0);
}
}
- for(int i=0,ni=m_nodes.size();i<ni;++i)
+ for(int i=0,ni=m_nodes.size();i<ni;++i)
{
- Node& n=m_nodes[i];
- n.m_v += (n.m_x-n.m_q)*vcf;
+ Node& n=m_nodes[i];
+ n.m_v += (n.m_x-n.m_q)*vcf;
}
}
-/* Apply clusters */
-dampClusters();
-applyClusters(true);
+ /* Apply clusters */
+ dampClusters();
+ applyClusters(true);
}
//
void btSoftBody::staticSolve(int iterations)
{
-for(int isolve=0;isolve<iterations;++isolve)
+ for(int isolve=0;isolve<iterations;++isolve)
{
- for(int iseq=0;iseq<m_cfg.m_psequence.size();++iseq)
+ for(int iseq=0;iseq<m_cfg.m_psequence.size();++iseq)
{
- getSolver(m_cfg.m_psequence[iseq])(this,1,0);
+ getSolver(m_cfg.m_psequence[iseq])(this,1,0);
}
}
}
@@ -1466,35 +1507,35 @@ for(int isolve=0;isolve<iterations;++isolve)
//
void btSoftBody::solveCommonConstraints(btSoftBody** /*bodies*/,int /*count*/,int /*iterations*/)
{
-/// placeholder
+ /// placeholder
}
//
void btSoftBody::solveClusters(const btAlignedObjectArray<btSoftBody*>& bodies)
{
-const int nb=bodies.size();
-int iterations=0;
-int i;
+ const int nb=bodies.size();
+ int iterations=0;
+ int i;
-for(i=0;i<nb;++i)
+ for(i=0;i<nb;++i)
{
- iterations=btMax(iterations,bodies[i]->m_cfg.citerations);
+ iterations=btMax(iterations,bodies[i]->m_cfg.citerations);
}
-for(i=0;i<nb;++i)
+ for(i=0;i<nb;++i)
{
- bodies[i]->prepareClusters(iterations);
+ bodies[i]->prepareClusters(iterations);
}
-for(i=0;i<iterations;++i)
+ for(i=0;i<iterations;++i)
{
- const btScalar sor=1;
- for(int j=0;j<nb;++j)
+ const btScalar sor=1;
+ for(int j=0;j<nb;++j)
{
- bodies[j]->solveClusters(sor);
+ bodies[j]->solveClusters(sor);
}
}
-for(i=0;i<nb;++i)
+ for(i=0;i<nb;++i)
{
- bodies[i]->cleanupClusters();
+ bodies[i]->cleanupClusters();
}
}
@@ -1506,48 +1547,54 @@ void btSoftBody::integrateMotion()
}
//
- btSoftBody::RayCaster::RayCaster(const btVector3& org,const btVector3& dir,btScalar mxt)
+btSoftBody::RayFromToCaster::RayFromToCaster(const btVector3& rayFrom,const btVector3& rayTo,btScalar mxt)
{
-o = org;
-d = dir;
-mint = mxt;
-face = 0;
-tests = 0;
+ m_rayFrom = rayFrom;
+ m_rayNormalizedDirection = (rayTo-rayFrom);
+ m_rayTo = rayTo;
+ m_mint = mxt;
+ m_face = 0;
+ m_tests = 0;
}
//
-void btSoftBody::RayCaster::Process(const btDbvtNode* leaf)
+void btSoftBody::RayFromToCaster::Process(const btDbvtNode* leaf)
{
-btSoftBody::Face& f=*(btSoftBody::Face*)leaf->data;
-const btScalar t=rayTriangle( o,d,
- f.m_n[0]->m_x,
- f.m_n[1]->m_x,
- f.m_n[2]->m_x,
- mint);
-if((t>0)&&(t<mint)) { mint=t;face=&f; }
-++tests;
+ btSoftBody::Face& f=*(btSoftBody::Face*)leaf->data;
+ const btScalar t=rayFromToTriangle( m_rayFrom,m_rayTo,m_rayNormalizedDirection,
+ f.m_n[0]->m_x,
+ f.m_n[1]->m_x,
+ f.m_n[2]->m_x,
+ m_mint);
+ if((t>0)&&(t<m_mint))
+ {
+ m_mint=t;m_face=&f;
+ }
+ ++m_tests;
}
//
-btScalar btSoftBody::RayCaster::rayTriangle( const btVector3& org,
- const btVector3& dir,
- const btVector3& a,
- const btVector3& b,
- const btVector3& c,
- btScalar maxt)
+btScalar btSoftBody::RayFromToCaster::rayFromToTriangle( const btVector3& rayFrom,
+ const btVector3& rayTo,
+ const btVector3& rayNormalizedDirection,
+ const btVector3& a,
+ const btVector3& b,
+ const btVector3& c,
+ btScalar maxt)
{
static const btScalar ceps=-SIMD_EPSILON*10;
static const btScalar teps=SIMD_EPSILON*10;
+
const btVector3 n=cross(b-a,c-a);
const btScalar d=dot(a,n);
- const btScalar den=dot(dir,n);
+ const btScalar den=dot(rayNormalizedDirection,n);
if(!btFuzzyZero(den))
{
- const btScalar num=dot(org,n)-d;
+ const btScalar num=dot(rayFrom,n)-d;
const btScalar t=-num/den;
if((t>teps)&&(t<maxt))
{
- const btVector3 hit=org+dir*t;
+ const btVector3 hit=rayFrom+rayNormalizedDirection*t;
if( (dot(n,cross(a-hit,b-hit))>ceps) &&
(dot(n,cross(b-hit,c-hit))>ceps) &&
(dot(n,cross(c-hit,a-hit))>ceps))
@@ -1569,9 +1616,9 @@ void btSoftBody::pointersToIndices()
for(i=0,ni=m_nodes.size();i<ni;++i)
{
if(m_nodes[i].m_leaf)
- {
+ {
m_nodes[i].m_leaf->data=*(void**)&i;
- }
+ }
}
for(i=0,ni=m_links.size();i<ni;++i)
{
@@ -1584,21 +1631,21 @@ void btSoftBody::pointersToIndices()
m_faces[i].m_n[1]=PTR2IDX(m_faces[i].m_n[1],base);
m_faces[i].m_n[2]=PTR2IDX(m_faces[i].m_n[2],base);
if(m_faces[i].m_leaf)
- {
+ {
m_faces[i].m_leaf->data=*(void**)&i;
- }
+ }
}
for(i=0,ni=m_anchors.size();i<ni;++i)
- {
+ {
m_anchors[i].m_node=PTR2IDX(m_anchors[i].m_node,base);
- }
+ }
for(i=0,ni=m_notes.size();i<ni;++i)
- {
+ {
for(int j=0;j<m_notes[i].m_rank;++j)
- {
+ {
m_notes[i].m_nodes[j]=PTR2IDX(m_notes[i].m_nodes[j],base);
- }
}
+ }
#undef PTR2IDX
}
@@ -1606,16 +1653,16 @@ void btSoftBody::pointersToIndices()
void btSoftBody::indicesToPointers(const int* map)
{
#define IDX2PTR(_p_,_b_) map?(&(_b_)[map[(((char*)_p_)-(char*)0)]]): \
- (&(_b_)[(((char*)_p_)-(char*)0)])
+ (&(_b_)[(((char*)_p_)-(char*)0)])
btSoftBody::Node* base=&m_nodes[0];
int i,ni;
for(i=0,ni=m_nodes.size();i<ni;++i)
{
if(m_nodes[i].m_leaf)
- {
+ {
m_nodes[i].m_leaf->data=&m_nodes[i];
- }
+ }
}
for(i=0,ni=m_links.size();i<ni;++i)
{
@@ -1628,110 +1675,116 @@ void btSoftBody::indicesToPointers(const int* map)
m_faces[i].m_n[1]=IDX2PTR(m_faces[i].m_n[1],base);
m_faces[i].m_n[2]=IDX2PTR(m_faces[i].m_n[2],base);
if(m_faces[i].m_leaf)
- {
+ {
m_faces[i].m_leaf->data=&m_faces[i];
- }
+ }
}
for(i=0,ni=m_anchors.size();i<ni;++i)
- {
+ {
m_anchors[i].m_node=IDX2PTR(m_anchors[i].m_node,base);
- }
+ }
for(i=0,ni=m_notes.size();i<ni;++i)
- {
+ {
for(int j=0;j<m_notes[i].m_rank;++j)
- {
+ {
m_notes[i].m_nodes[j]=IDX2PTR(m_notes[i].m_nodes[j],base);
- }
}
+ }
#undef IDX2PTR
}
//
-int btSoftBody::rayCast(const btVector3& org,const btVector3& dir,
+int btSoftBody::rayTest(const btVector3& rayFrom,const btVector3& rayTo,
btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const
{
int cnt=0;
if(bcountonly||m_fdbvt.empty())
- {/* Full search */
+ {/* Full search */
+ btVector3 dir = rayTo-rayFrom;
+ dir.normalize();
+
for(int i=0,ni=m_faces.size();i<ni;++i)
- {
+ {
const btSoftBody::Face& f=m_faces[i];
- const btScalar t=RayCaster::rayTriangle( org,dir,
- f.m_n[0]->m_x,
- f.m_n[1]->m_x,
- f.m_n[2]->m_x,
- mint);
+
+ const btScalar t=RayFromToCaster::rayFromToTriangle( rayFrom,rayTo,dir,
+ f.m_n[0]->m_x,
+ f.m_n[1]->m_x,
+ f.m_n[2]->m_x,
+ mint);
if(t>0)
- {
+ {
++cnt;
if(!bcountonly)
- {
+ {
feature=btSoftBody::eFeature::Face;
index=i;
mint=t;
- }
}
}
}
- else
- {/* Use dbvt */
- RayCaster collider(org,dir,mint);
- btDbvt::collideRAY(m_fdbvt.m_root,org,dir,collider);
- if(collider.face)
- {
- mint=collider.mint;
+ }
+ else
+ {/* Use dbvt */
+ RayFromToCaster collider(rayFrom,rayTo,mint);
+
+ btDbvt::rayTest(m_fdbvt.m_root,rayFrom,rayTo,collider);
+ if(collider.m_face)
+ {
+ mint=collider.m_mint;
feature=btSoftBody::eFeature::Face;
- index=(int)(collider.face-&m_faces[0]);
+ index=(int)(collider.m_face-&m_faces[0]);
cnt=1;
- }
}
+ }
return(cnt);
}
//
void btSoftBody::initializeFaceTree()
{
-m_fdbvt.clear();
-for(int i=0;i<m_faces.size();++i)
+ m_fdbvt.clear();
+ for(int i=0;i<m_faces.size();++i)
{
- Face& f=m_faces[i];
- f.m_leaf=m_fdbvt.insert(VolumeOf(f,0),&f);
+ Face& f=m_faces[i];
+ f.m_leaf=m_fdbvt.insert(VolumeOf(f,0),&f);
}
}
//
btVector3 btSoftBody::evaluateCom() const
{
-btVector3 com(0,0,0);
-if(m_pose.m_bframe)
+ btVector3 com(0,0,0);
+ if(m_pose.m_bframe)
{
- for(int i=0,ni=m_nodes.size();i<ni;++i)
+ for(int i=0,ni=m_nodes.size();i<ni;++i)
{
- com+=m_nodes[i].m_x*m_pose.m_wgh[i];
+ com+=m_nodes[i].m_x*m_pose.m_wgh[i];
}
}
return(com);
}
-
+
//
-bool btSoftBody::checkContact( btRigidBody* prb,
- const btVector3& x,
- btScalar margin,
- btSoftBody::sCti& cti) const
+bool btSoftBody::checkContact( btCollisionObject* colObj,
+ const btVector3& x,
+ btScalar margin,
+ btSoftBody::sCti& cti) const
{
btVector3 nrm;
- btCollisionShape* shp=prb->getCollisionShape();
- const btTransform& wtr=prb->getInterpolationWorldTransform();
+ btCollisionShape* shp=colObj->getCollisionShape();
+ btRigidBody* tmpRigid = btRigidBody::upcast(colObj);
+ const btTransform& wtr=tmpRigid? tmpRigid->getInterpolationWorldTransform() : colObj->getWorldTransform();
btScalar dst=m_worldInfo->m_sparsesdf.Evaluate( wtr.invXform(x),
- shp,
- nrm,
- margin);
+ shp,
+ nrm,
+ margin);
if(dst<0)
{
- cti.m_body = prb;
+ cti.m_colObj = colObj;
cti.m_normal = wtr.getBasis()*nrm;
cti.m_offset = -dot( cti.m_normal,
- x-cti.m_normal*dst);
+ x-cti.m_normal*dst);
return(true);
}
return(false);
@@ -1751,7 +1804,7 @@ void btSoftBody::updateNormals()
{
btSoftBody::Face& f=m_faces[i];
const btVector3 n=cross(f.m_n[1]->m_x-f.m_n[0]->m_x,
- f.m_n[2]->m_x-f.m_n[0]->m_x);
+ f.m_n[2]->m_x-f.m_n[0]->m_x);
f.m_normal=n.normalized();
f.m_n[0]->m_n+=n;
f.m_n[1]->m_n+=n;
@@ -1769,28 +1822,28 @@ void btSoftBody::updateNormals()
void btSoftBody::updateBounds()
{
if(m_ndbvt.m_root)
- {
+ {
const btVector3& mins=m_ndbvt.m_root->volume.Mins();
const btVector3& maxs=m_ndbvt.m_root->volume.Maxs();
const btScalar csm=getCollisionShape()->getMargin();
const btVector3 mrg=btVector3( csm,
- csm,
- csm)*1; // ??? to investigate...
+ csm,
+ csm)*1; // ??? to investigate...
m_bounds[0]=mins-mrg;
m_bounds[1]=maxs+mrg;
- if(0!=getBroadphaseHandle())
- {
- m_worldInfo->m_broadphase->setAabb( getBroadphaseHandle(),
- m_bounds[0],
- m_bounds[1],
- m_worldInfo->m_dispatcher);
- }
+ if(0!=getBroadphaseHandle())
+ {
+ m_worldInfo->m_broadphase->setAabb( getBroadphaseHandle(),
+ m_bounds[0],
+ m_bounds[1],
+ m_worldInfo->m_dispatcher);
}
- else
- {
+ }
+ else
+ {
m_bounds[0]=
- m_bounds[1]=btVector3(0,0,0);
- }
+ m_bounds[1]=btVector3(0,0,0);
+ }
}
@@ -1821,12 +1874,12 @@ void btSoftBody::updatePose()
pose.m_rot=r;
pose.m_scl=pose.m_aqq*r.transpose()*Apq;
if(m_cfg.maxvolume>1)
- {
+ {
const btScalar idet=Clamp<btScalar>( 1/pose.m_scl.determinant(),
- 1,m_cfg.maxvolume);
+ 1,m_cfg.maxvolume);
pose.m_scl=Mul(pose.m_scl,idet);
- }
-
+ }
+
}
}
@@ -1881,53 +1934,53 @@ void btSoftBody::initializeClusters()
{
int i;
-for( i=0;i<m_clusters.size();++i)
+ for( i=0;i<m_clusters.size();++i)
{
- Cluster& c=*m_clusters[i];
- c.m_imass=0;
- c.m_masses.resize(c.m_nodes.size());
- for(int j=0;j<c.m_nodes.size();++j)
+ Cluster& c=*m_clusters[i];
+ c.m_imass=0;
+ c.m_masses.resize(c.m_nodes.size());
+ for(int j=0;j<c.m_nodes.size();++j)
{
- c.m_masses[j] = c.m_nodes[j]->m_im>0?1/c.m_nodes[j]->m_im:0;
- c.m_imass += c.m_masses[j];
+ c.m_masses[j] = c.m_nodes[j]->m_im>0?1/c.m_nodes[j]->m_im:0;
+ c.m_imass += c.m_masses[j];
}
- c.m_imass = 1/c.m_imass;
- c.m_com = btSoftBody::clusterCom(&c);
- c.m_lv = btVector3(0,0,0);
- c.m_av = btVector3(0,0,0);
- c.m_leaf = 0;
- /* Inertia */
- btMatrix3x3& ii=c.m_locii;
- ii[0]=ii[1]=ii[2]=btVector3(0,0,0);
- {
- int i,ni;
+ c.m_imass = 1/c.m_imass;
+ c.m_com = btSoftBody::clusterCom(&c);
+ c.m_lv = btVector3(0,0,0);
+ c.m_av = btVector3(0,0,0);
+ c.m_leaf = 0;
+ /* Inertia */
+ btMatrix3x3& ii=c.m_locii;
+ ii[0]=ii[1]=ii[2]=btVector3(0,0,0);
+ {
+ int i,ni;
- for(i=0,ni=c.m_nodes.size();i<ni;++i)
- {
- const btVector3 k=c.m_nodes[i]->m_x-c.m_com;
- const btVector3 q=k*k;
- const btScalar m=c.m_masses[i];
- ii[0][0] += m*(q[1]+q[2]);
- ii[1][1] += m*(q[0]+q[2]);
- ii[2][2] += m*(q[0]+q[1]);
- ii[0][1] -= m*k[0]*k[1];
- ii[0][2] -= m*k[0]*k[2];
- ii[1][2] -= m*k[1]*k[2];
- }
- }
- ii[1][0]=ii[0][1];
- ii[2][0]=ii[0][2];
- ii[2][1]=ii[1][2];
- ii=ii.inverse();
- /* Frame */
- c.m_framexform.setIdentity();
- c.m_framexform.setOrigin(c.m_com);
- c.m_framerefs.resize(c.m_nodes.size());
- {
- int i;
- for(i=0;i<c.m_framerefs.size();++i)
+ for(i=0,ni=c.m_nodes.size();i<ni;++i)
+ {
+ const btVector3 k=c.m_nodes[i]->m_x-c.m_com;
+ const btVector3 q=k*k;
+ const btScalar m=c.m_masses[i];
+ ii[0][0] += m*(q[1]+q[2]);
+ ii[1][1] += m*(q[0]+q[2]);
+ ii[2][2] += m*(q[0]+q[1]);
+ ii[0][1] -= m*k[0]*k[1];
+ ii[0][2] -= m*k[0]*k[2];
+ ii[1][2] -= m*k[1]*k[2];
+ }
+ }
+ ii[1][0]=ii[0][1];
+ ii[2][0]=ii[0][2];
+ ii[2][1]=ii[1][2];
+ ii=ii.inverse();
+ /* Frame */
+ c.m_framexform.setIdentity();
+ c.m_framexform.setOrigin(c.m_com);
+ c.m_framerefs.resize(c.m_nodes.size());
+ {
+ int i;
+ for(i=0;i<c.m_framerefs.size();++i)
{
- c.m_framerefs[i]=c.m_nodes[i]->m_x-c.m_com;
+ c.m_framerefs[i]=c.m_nodes[i]->m_x-c.m_com;
}
}
}
@@ -1936,49 +1989,49 @@ for( i=0;i<m_clusters.size();++i)
//
void btSoftBody::updateClusters()
{
-BT_PROFILE("UpdateClusters");
-int i;
-
-for(i=0;i<m_clusters.size();++i)
- {
- btSoftBody::Cluster& c=*m_clusters[i];
- const int n=c.m_nodes.size();
- const btScalar invn=1/(btScalar)n;
- if(n)
- {
- /* Frame */
- const btScalar eps=btScalar(0.0001);
- btMatrix3x3 m,r,s;
- m[0]=m[1]=m[2]=btVector3(0,0,0);
- m[0][0]=eps*1;
- m[1][1]=eps*2;
- m[2][2]=eps*3;
- c.m_com=clusterCom(&c);
- for(int i=0;i<c.m_nodes.size();++i)
+ BT_PROFILE("UpdateClusters");
+ int i;
+
+ for(i=0;i<m_clusters.size();++i)
+ {
+ btSoftBody::Cluster& c=*m_clusters[i];
+ const int n=c.m_nodes.size();
+ const btScalar invn=1/(btScalar)n;
+ if(n)
+ {
+ /* Frame */
+ const btScalar eps=btScalar(0.0001);
+ btMatrix3x3 m,r,s;
+ m[0]=m[1]=m[2]=btVector3(0,0,0);
+ m[0][0]=eps*1;
+ m[1][1]=eps*2;
+ m[2][2]=eps*3;
+ c.m_com=clusterCom(&c);
+ for(int i=0;i<c.m_nodes.size();++i)
{
- const btVector3 a=c.m_nodes[i]->m_x-c.m_com;
- const btVector3& b=c.m_framerefs[i];
- m[0]+=a[0]*b;m[1]+=a[1]*b;m[2]+=a[2]*b;
+ const btVector3 a=c.m_nodes[i]->m_x-c.m_com;
+ const btVector3& b=c.m_framerefs[i];
+ m[0]+=a[0]*b;m[1]+=a[1]*b;m[2]+=a[2]*b;
}
- PolarDecompose(m,r,s);
- c.m_framexform.setOrigin(c.m_com);
- c.m_framexform.setBasis(r);
- /* Inertia */
- #if 1/* Constant */
- c.m_invwi=c.m_framexform.getBasis()*c.m_locii*c.m_framexform.getBasis().transpose();
- #else
- #if 0/* Sphere */
+ PolarDecompose(m,r,s);
+ c.m_framexform.setOrigin(c.m_com);
+ c.m_framexform.setBasis(r);
+ /* Inertia */
+#if 1/* Constant */
+ c.m_invwi=c.m_framexform.getBasis()*c.m_locii*c.m_framexform.getBasis().transpose();
+#else
+#if 0/* Sphere */
const btScalar rk=(2*c.m_extents.length2())/(5*c.m_imass);
const btVector3 inertia(rk,rk,rk);
const btVector3 iin(btFabs(inertia[0])>SIMD_EPSILON?1/inertia[0]:0,
- btFabs(inertia[1])>SIMD_EPSILON?1/inertia[1]:0,
- btFabs(inertia[2])>SIMD_EPSILON?1/inertia[2]:0);
-
+ btFabs(inertia[1])>SIMD_EPSILON?1/inertia[1]:0,
+ btFabs(inertia[2])>SIMD_EPSILON?1/inertia[2]:0);
+
c.m_invwi=c.m_xform.getBasis().scaled(iin)*c.m_xform.getBasis().transpose();
- #else/* Actual */
+#else/* Actual */
c.m_invwi[0]=c.m_invwi[1]=c.m_invwi[2]=btVector3(0,0,0);
for(int i=0;i<n;++i)
- {
+ {
const btVector3 k=c.m_nodes[i]->m_x-c.m_com;
const btVector3 q=k*k;
const btScalar m=1/c.m_nodes[i]->m_im;
@@ -1988,74 +2041,79 @@ for(i=0;i<m_clusters.size();++i)
c.m_invwi[0][1] -= m*k[0]*k[1];
c.m_invwi[0][2] -= m*k[0]*k[2];
c.m_invwi[1][2] -= m*k[1]*k[2];
- }
+ }
c.m_invwi[1][0]=c.m_invwi[0][1];
c.m_invwi[2][0]=c.m_invwi[0][2];
c.m_invwi[2][1]=c.m_invwi[1][2];
c.m_invwi=c.m_invwi.inverse();
- #endif
- #endif
- /* Velocities */
- c.m_lv=btVector3(0,0,0);
- c.m_av=btVector3(0,0,0);
- {
- int i;
-
- for(i=0;i<n;++i)
+#endif
+#endif
+ /* Velocities */
+ c.m_lv=btVector3(0,0,0);
+ c.m_av=btVector3(0,0,0);
{
- const btVector3 v=c.m_nodes[i]->m_v*c.m_masses[i];
- c.m_lv += v;
- c.m_av += cross(c.m_nodes[i]->m_x-c.m_com,v);
+ int i;
+
+ for(i=0;i<n;++i)
+ {
+ const btVector3 v=c.m_nodes[i]->m_v*c.m_masses[i];
+ c.m_lv += v;
+ c.m_av += cross(c.m_nodes[i]->m_x-c.m_com,v);
+ }
}
- }
- c.m_lv=c.m_imass*c.m_lv*(1-c.m_ldamping);
- c.m_av=c.m_invwi*c.m_av*(1-c.m_adamping);
- c.m_vimpulses[0] =
- c.m_vimpulses[1] = btVector3(0,0,0);
- c.m_dimpulses[0] =
- c.m_dimpulses[1] = btVector3(0,0,0);
- c.m_nvimpulses = 0;
- c.m_ndimpulses = 0;
- /* Matching */
- if(c.m_matching>0)
+ c.m_lv=c.m_imass*c.m_lv*(1-c.m_ldamping);
+ c.m_av=c.m_invwi*c.m_av*(1-c.m_adamping);
+ c.m_vimpulses[0] =
+ c.m_vimpulses[1] = btVector3(0,0,0);
+ c.m_dimpulses[0] =
+ c.m_dimpulses[1] = btVector3(0,0,0);
+ c.m_nvimpulses = 0;
+ c.m_ndimpulses = 0;
+ /* Matching */
+ if(c.m_matching>0)
{
- for(int j=0;j<c.m_nodes.size();++j)
+ for(int j=0;j<c.m_nodes.size();++j)
{
- Node& n=*c.m_nodes[j];
- const btVector3 x=c.m_framexform*c.m_framerefs[j];
- n.m_x=Lerp(n.m_x,x,c.m_matching);
+ Node& n=*c.m_nodes[j];
+ const btVector3 x=c.m_framexform*c.m_framerefs[j];
+ n.m_x=Lerp(n.m_x,x,c.m_matching);
}
- }
- /* Dbvt */
- if(c.m_collide)
+ }
+ /* Dbvt */
+ if(c.m_collide)
{
- btVector3 mi=c.m_nodes[0]->m_x;
- btVector3 mx=mi;
- for(int j=1;j<n;++j)
+ btVector3 mi=c.m_nodes[0]->m_x;
+ btVector3 mx=mi;
+ for(int j=1;j<n;++j)
{
- mi.setMin(c.m_nodes[j]->m_x);
- mx.setMax(c.m_nodes[j]->m_x);
+ mi.setMin(c.m_nodes[j]->m_x);
+ mx.setMax(c.m_nodes[j]->m_x);
}
- const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(mi,mx);
- if(c.m_leaf)
- m_cdbvt.update(c.m_leaf,bounds,c.m_lv*m_sst.sdt*3,m_sst.radmrg);
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(mi,mx);
+ if(c.m_leaf)
+ m_cdbvt.update(c.m_leaf,bounds,c.m_lv*m_sst.sdt*3,m_sst.radmrg);
else
- c.m_leaf=m_cdbvt.insert(bounds,&c);
+ c.m_leaf=m_cdbvt.insert(bounds,&c);
}
}
}
+
+
}
+
+
+
//
void btSoftBody::cleanupClusters()
{
-for(int i=0;i<m_joints.size();++i)
+ for(int i=0;i<m_joints.size();++i)
{
- m_joints[i]->Terminate(m_sst.sdt);
- if(m_joints[i]->m_delete)
+ m_joints[i]->Terminate(m_sst.sdt);
+ if(m_joints[i]->m_delete)
{
- btAlignedFree(m_joints[i]);
- m_joints.remove(m_joints[i--]);
+ btAlignedFree(m_joints[i]);
+ m_joints.remove(m_joints[i--]);
}
}
}
@@ -2063,9 +2121,9 @@ for(int i=0;i<m_joints.size();++i)
//
void btSoftBody::prepareClusters(int iterations)
{
-for(int i=0;i<m_joints.size();++i)
+ for(int i=0;i<m_joints.size();++i)
{
- m_joints[i]->Prepare(m_sst.sdt,iterations);
+ m_joints[i]->Prepare(m_sst.sdt,iterations);
}
}
@@ -2073,50 +2131,51 @@ for(int i=0;i<m_joints.size();++i)
//
void btSoftBody::solveClusters(btScalar sor)
{
-for(int i=0,ni=m_joints.size();i<ni;++i)
+ for(int i=0,ni=m_joints.size();i<ni;++i)
{
- m_joints[i]->Solve(m_sst.sdt,sor);
+ m_joints[i]->Solve(m_sst.sdt,sor);
}
}
//
void btSoftBody::applyClusters(bool drift)
{
-BT_PROFILE("ApplyClusters");
-const btScalar f0=m_sst.sdt;
-const btScalar f1=f0/2;
-btAlignedObjectArray<btVector3> deltas;
-btAlignedObjectArray<btScalar> weights;
-deltas.resize(m_nodes.size(),btVector3(0,0,0));
-weights.resize(m_nodes.size(),0);
-int i;
+ BT_PROFILE("ApplyClusters");
+ const btScalar f0=m_sst.sdt;
+ const btScalar f1=f0/2;
+ btAlignedObjectArray<btVector3> deltas;
+ btAlignedObjectArray<btScalar> weights;
+ deltas.resize(m_nodes.size(),btVector3(0,0,0));
+ weights.resize(m_nodes.size(),0);
+ int i;
-if(drift)
+ if(drift)
{
- for(i=0;i<m_clusters.size();++i)
+ for(i=0;i<m_clusters.size();++i)
{
- Cluster& c=*m_clusters[i];
- if(c.m_ndimpulses)
+ Cluster& c=*m_clusters[i];
+ if(c.m_ndimpulses)
{
- c.m_dimpulses[0]/=(btScalar)c.m_ndimpulses;
- c.m_dimpulses[1]/=(btScalar)c.m_ndimpulses;
+ c.m_dimpulses[0]/=(btScalar)c.m_ndimpulses;
+ c.m_dimpulses[1]/=(btScalar)c.m_ndimpulses;
}
}
}
-for(i=0;i<m_clusters.size();++i)
+
+ for(i=0;i<m_clusters.size();++i)
{
- Cluster& c=*m_clusters[i];
- if(0<(drift?c.m_ndimpulses:c.m_nvimpulses))
+ Cluster& c=*m_clusters[i];
+ if(0<(drift?c.m_ndimpulses:c.m_nvimpulses))
{
- const btVector3 v=(drift?c.m_dimpulses[0]:c.m_vimpulses[0])*m_sst.sdt;
- const btVector3 w=(drift?c.m_dimpulses[1]:c.m_vimpulses[1])*m_sst.sdt;
- for(int j=0;j<c.m_nodes.size();++j)
+ const btVector3 v=(drift?c.m_dimpulses[0]:c.m_vimpulses[0])*m_sst.sdt;
+ const btVector3 w=(drift?c.m_dimpulses[1]:c.m_vimpulses[1])*m_sst.sdt;
+ for(int j=0;j<c.m_nodes.size();++j)
{
- const int idx=int(c.m_nodes[j]-&m_nodes[0]);
- const btVector3& x=c.m_nodes[j]->m_x;
- const btScalar q=c.m_masses[j];
- deltas[idx] += (v+cross(w,x-c.m_com))*q;
- weights[idx] += q;
+ const int idx=int(c.m_nodes[j]-&m_nodes[0]);
+ const btVector3& x=c.m_nodes[j]->m_x;
+ const btScalar q=c.m_masses[j];
+ deltas[idx] += (v+cross(w,x-c.m_com))*q;
+ weights[idx] += q;
}
}
}
@@ -2131,18 +2190,21 @@ void btSoftBody::dampClusters()
{
int i;
-for(i=0;i<m_clusters.size();++i)
+ for(i=0;i<m_clusters.size();++i)
{
- Cluster& c=*m_clusters[i];
- if(c.m_ndamping>0)
+ Cluster& c=*m_clusters[i];
+ if(c.m_ndamping>0)
{
- for(int j=0;j<c.m_nodes.size();++j)
+ for(int j=0;j<c.m_nodes.size();++j)
{
- Node& n=*c.m_nodes[j];
- if(n.m_im>0)
+ Node& n=*c.m_nodes[j];
+ if(n.m_im>0)
{
- const btVector3 vx=c.m_lv+cross(c.m_av,c.m_nodes[j]->m_q-c.m_com);
- n.m_v += c.m_ndamping*(vx-n.m_v);
+ const btVector3 vx=c.m_lv+cross(c.m_av,c.m_nodes[j]->m_q-c.m_com);
+ if(vx.length2()<=n.m_v.length2())
+ {
+ n.m_v += c.m_ndamping*(vx-n.m_v);
+ }
}
}
}
@@ -2152,154 +2214,155 @@ for(i=0;i<m_clusters.size();++i)
//
void btSoftBody::Joint::Prepare(btScalar dt,int)
{
-m_bodies[0].activate();
-m_bodies[1].activate();
+ m_bodies[0].activate();
+ m_bodies[1].activate();
}
//
void btSoftBody::LJoint::Prepare(btScalar dt,int iterations)
{
-static const btScalar maxdrift=4;
-Joint::Prepare(dt,iterations);
-m_rpos[0] = m_bodies[0].xform()*m_refs[0];
-m_rpos[1] = m_bodies[1].xform()*m_refs[1];
-m_drift = Clamp(m_rpos[0]-m_rpos[1],maxdrift)*m_erp/dt;
-m_rpos[0] -= m_bodies[0].xform().getOrigin();
-m_rpos[1] -= m_bodies[1].xform().getOrigin();
-m_massmatrix = ImpulseMatrix( m_bodies[0].invMass(),m_bodies[0].invWorldInertia(),m_rpos[0],
- m_bodies[1].invMass(),m_bodies[1].invWorldInertia(),m_rpos[1]);
-if(m_split>0)
+ static const btScalar maxdrift=4;
+ Joint::Prepare(dt,iterations);
+ m_rpos[0] = m_bodies[0].xform()*m_refs[0];
+ m_rpos[1] = m_bodies[1].xform()*m_refs[1];
+ m_drift = Clamp(m_rpos[0]-m_rpos[1],maxdrift)*m_erp/dt;
+ m_rpos[0] -= m_bodies[0].xform().getOrigin();
+ m_rpos[1] -= m_bodies[1].xform().getOrigin();
+ m_massmatrix = ImpulseMatrix( m_bodies[0].invMass(),m_bodies[0].invWorldInertia(),m_rpos[0],
+ m_bodies[1].invMass(),m_bodies[1].invWorldInertia(),m_rpos[1]);
+ if(m_split>0)
{
- m_sdrift = m_massmatrix*(m_drift*m_split);
- m_drift *= 1-m_split;
+ m_sdrift = m_massmatrix*(m_drift*m_split);
+ m_drift *= 1-m_split;
}
-m_drift /=(btScalar)iterations;
+ m_drift /=(btScalar)iterations;
}
//
void btSoftBody::LJoint::Solve(btScalar dt,btScalar sor)
{
-const btVector3 va=m_bodies[0].velocity(m_rpos[0]);
-const btVector3 vb=m_bodies[1].velocity(m_rpos[1]);
-const btVector3 vr=va-vb;
-btSoftBody::Impulse impulse;
-impulse.m_asVelocity = 1;
-impulse.m_velocity = m_massmatrix*(m_drift+vr*m_cfm)*sor;
-m_bodies[0].applyImpulse(-impulse,m_rpos[0]);
-m_bodies[1].applyImpulse( impulse,m_rpos[1]);
+ const btVector3 va=m_bodies[0].velocity(m_rpos[0]);
+ const btVector3 vb=m_bodies[1].velocity(m_rpos[1]);
+ const btVector3 vr=va-vb;
+ btSoftBody::Impulse impulse;
+ impulse.m_asVelocity = 1;
+ impulse.m_velocity = m_massmatrix*(m_drift+vr*m_cfm)*sor;
+ m_bodies[0].applyImpulse(-impulse,m_rpos[0]);
+ m_bodies[1].applyImpulse( impulse,m_rpos[1]);
}
//
void btSoftBody::LJoint::Terminate(btScalar dt)
{
-if(m_split>0)
+ if(m_split>0)
{
- m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]);
- m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]);
+ m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]);
+ m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]);
}
}
//
void btSoftBody::AJoint::Prepare(btScalar dt,int iterations)
{
-static const btScalar maxdrift=SIMD_PI/16;
-m_icontrol->Prepare(this);
-Joint::Prepare(dt,iterations);
-m_axis[0] = m_bodies[0].xform().getBasis()*m_refs[0];
-m_axis[1] = m_bodies[1].xform().getBasis()*m_refs[1];
-m_drift = NormalizeAny(cross(m_axis[1],m_axis[0]));
-m_drift *= btMin(maxdrift,btAcos(Clamp<btScalar>(dot(m_axis[0],m_axis[1]),-1,+1)));
-m_drift *= m_erp/dt;
-m_massmatrix= AngularImpulseMatrix(m_bodies[0].invWorldInertia(),m_bodies[1].invWorldInertia());
-if(m_split>0)
+ static const btScalar maxdrift=SIMD_PI/16;
+ m_icontrol->Prepare(this);
+ Joint::Prepare(dt,iterations);
+ m_axis[0] = m_bodies[0].xform().getBasis()*m_refs[0];
+ m_axis[1] = m_bodies[1].xform().getBasis()*m_refs[1];
+ m_drift = NormalizeAny(cross(m_axis[1],m_axis[0]));
+ m_drift *= btMin(maxdrift,btAcos(Clamp<btScalar>(dot(m_axis[0],m_axis[1]),-1,+1)));
+ m_drift *= m_erp/dt;
+ m_massmatrix= AngularImpulseMatrix(m_bodies[0].invWorldInertia(),m_bodies[1].invWorldInertia());
+ if(m_split>0)
{
- m_sdrift = m_massmatrix*(m_drift*m_split);
- m_drift *= 1-m_split;
+ m_sdrift = m_massmatrix*(m_drift*m_split);
+ m_drift *= 1-m_split;
}
-m_drift /=(btScalar)iterations;
+ m_drift /=(btScalar)iterations;
}
//
void btSoftBody::AJoint::Solve(btScalar dt,btScalar sor)
{
-const btVector3 va=m_bodies[0].angularVelocity();
-const btVector3 vb=m_bodies[1].angularVelocity();
-const btVector3 vr=va-vb;
-const btScalar sp=dot(vr,m_axis[0]);
-const btVector3 vc=vr-m_axis[0]*m_icontrol->Speed(this,sp);
-btSoftBody::Impulse impulse;
-impulse.m_asVelocity = 1;
-impulse.m_velocity = m_massmatrix*(m_drift+vc*m_cfm)*sor;
-m_bodies[0].applyAImpulse(-impulse);
-m_bodies[1].applyAImpulse( impulse);
+ const btVector3 va=m_bodies[0].angularVelocity();
+ const btVector3 vb=m_bodies[1].angularVelocity();
+ const btVector3 vr=va-vb;
+ const btScalar sp=dot(vr,m_axis[0]);
+ const btVector3 vc=vr-m_axis[0]*m_icontrol->Speed(this,sp);
+ btSoftBody::Impulse impulse;
+ impulse.m_asVelocity = 1;
+ impulse.m_velocity = m_massmatrix*(m_drift+vc*m_cfm)*sor;
+ m_bodies[0].applyAImpulse(-impulse);
+ m_bodies[1].applyAImpulse( impulse);
}
//
void btSoftBody::AJoint::Terminate(btScalar dt)
{
-if(m_split>0)
+ if(m_split>0)
{
- m_bodies[0].applyDAImpulse(-m_sdrift);
- m_bodies[1].applyDAImpulse( m_sdrift);
+ m_bodies[0].applyDAImpulse(-m_sdrift);
+ m_bodies[1].applyDAImpulse( m_sdrift);
}
}
//
void btSoftBody::CJoint::Prepare(btScalar dt,int iterations)
{
-Joint::Prepare(dt,iterations);
-const bool dodrift=(m_life==0);
-m_delete=(++m_life)>m_maxlife;
-if(dodrift)
+ Joint::Prepare(dt,iterations);
+ const bool dodrift=(m_life==0);
+ m_delete=(++m_life)>m_maxlife;
+ if(dodrift)
{
- m_drift=m_drift*m_erp/dt;
- if(m_split>0)
+ m_drift=m_drift*m_erp/dt;
+ if(m_split>0)
{
- m_sdrift = m_massmatrix*(m_drift*m_split);
- m_drift *= 1-m_split;
+ m_sdrift = m_massmatrix*(m_drift*m_split);
+ m_drift *= 1-m_split;
}
- m_drift/=(btScalar)iterations;
+ m_drift/=(btScalar)iterations;
}
else
{
- m_drift=m_sdrift=btVector3(0,0,0);
+ m_drift=m_sdrift=btVector3(0,0,0);
}
}
//
void btSoftBody::CJoint::Solve(btScalar dt,btScalar sor)
{
-const btVector3 va=m_bodies[0].velocity(m_rpos[0]);
-const btVector3 vb=m_bodies[1].velocity(m_rpos[1]);
-const btVector3 vrel=va-vb;
-const btScalar rvac=dot(vrel,m_normal);
-btSoftBody::Impulse impulse;
-impulse.m_asVelocity = 1;
-impulse.m_velocity = m_drift;
-if(rvac<0)
+ const btVector3 va=m_bodies[0].velocity(m_rpos[0]);
+ const btVector3 vb=m_bodies[1].velocity(m_rpos[1]);
+ const btVector3 vrel=va-vb;
+ const btScalar rvac=dot(vrel,m_normal);
+ btSoftBody::Impulse impulse;
+ impulse.m_asVelocity = 1;
+ impulse.m_velocity = m_drift;
+ if(rvac<0)
{
- const btVector3 iv=m_normal*rvac;
- const btVector3 fv=vrel-iv;
- impulse.m_velocity += iv+fv*m_friction;
+ const btVector3 iv=m_normal*rvac;
+ const btVector3 fv=vrel-iv;
+ impulse.m_velocity += iv+fv*m_friction;
}
-impulse.m_velocity=m_massmatrix*impulse.m_velocity*sor;
-m_bodies[0].applyImpulse(-impulse,m_rpos[0]);
-m_bodies[1].applyImpulse( impulse,m_rpos[1]);
+ impulse.m_velocity=m_massmatrix*impulse.m_velocity*sor;
+ m_bodies[0].applyImpulse(-impulse,m_rpos[0]);
+ m_bodies[1].applyImpulse( impulse,m_rpos[1]);
}
//
void btSoftBody::CJoint::Terminate(btScalar dt)
{
-if(m_split>0)
+ if(m_split>0)
{
- m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]);
- m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]);
+ m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]);
+ m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]);
}
}
//
void btSoftBody::applyForces()
{
+
BT_PROFILE("SoftBody applyForces");
const btScalar dt=m_sst.sdt;
const btScalar kLF=m_cfg.kLF;
@@ -2311,14 +2374,14 @@ void btSoftBody::applyForces()
const bool as_pressure=kPR!=0;
const bool as_volume=kVC>0;
const bool as_aero= as_lift ||
- as_drag ;
+ as_drag ;
const bool as_vaero= as_aero &&
- (m_cfg.aeromodel<btSoftBody::eAeroModel::F_TwoSided);
+ (m_cfg.aeromodel<btSoftBody::eAeroModel::F_TwoSided);
const bool as_faero= as_aero &&
- (m_cfg.aeromodel>=btSoftBody::eAeroModel::F_TwoSided);
+ (m_cfg.aeromodel>=btSoftBody::eAeroModel::F_TwoSided);
const bool use_medium= as_aero;
const bool use_volume= as_pressure ||
- as_volume ;
+ as_volume ;
btScalar volume=0;
btScalar ivolumetp=0;
btScalar dvolumetv=0;
@@ -2447,12 +2510,10 @@ void btSoftBody::PSolve_RContacts(btSoftBody* psb,btScalar kst,btScalar ti)
for(int i=0,ni=psb->m_rcontacts.size();i<ni;++i)
{
const RContact& c=psb->m_rcontacts[i];
- ///skip object that don't have collision response
- if (!psb->getWorldInfo()->m_dispatcher->needsResponse(psb,c.m_cti.m_body))
- continue;
-
const sCti& cti=c.m_cti;
- const btVector3 va=cti.m_body->getVelocityInLocalPoint(c.m_c1)*dt;
+ btRigidBody* tmpRigid = btRigidBody::upcast(cti.m_colObj);
+
+ const btVector3 va=tmpRigid ? tmpRigid->getVelocityInLocalPoint(c.m_c1)*dt : btVector3(0,0,0);
const btVector3 vb=c.m_node->m_x-c.m_node->m_q;
const btVector3 vr=vb-va;
const btScalar dn=dot(vr,cti.m_normal);
@@ -2462,7 +2523,8 @@ void btSoftBody::PSolve_RContacts(btSoftBody* psb,btScalar kst,btScalar ti)
const btVector3 fv=vr-cti.m_normal*dn;
const btVector3 impulse=c.m_c0*((vr-fv*c.m_c3+cti.m_normal*(dp*c.m_c4))*kst);
c.m_node->m_x-=impulse*c.m_c2;
- c.m_cti.m_body->applyImpulse(impulse,c.m_c1);
+ if (tmpRigid)
+ tmpRigid->applyImpulse(impulse,c.m_c1);
}
}
}
@@ -2470,32 +2532,32 @@ void btSoftBody::PSolve_RContacts(btSoftBody* psb,btScalar kst,btScalar ti)
//
void btSoftBody::PSolve_SContacts(btSoftBody* psb,btScalar,btScalar ti)
{
-for(int i=0,ni=psb->m_scontacts.size();i<ni;++i)
+ for(int i=0,ni=psb->m_scontacts.size();i<ni;++i)
{
- const SContact& c=psb->m_scontacts[i];
- const btVector3& nr=c.m_normal;
- Node& n=*c.m_node;
- Face& f=*c.m_face;
- const btVector3 p=BaryEval( f.m_n[0]->m_x,
- f.m_n[1]->m_x,
- f.m_n[2]->m_x,
- c.m_weights);
- const btVector3 q=BaryEval( f.m_n[0]->m_q,
- f.m_n[1]->m_q,
- f.m_n[2]->m_q,
- c.m_weights);
- const btVector3 vr=(n.m_x-n.m_q)-(p-q);
- btVector3 corr(0,0,0);
- if(dot(vr,nr)<0)
+ const SContact& c=psb->m_scontacts[i];
+ const btVector3& nr=c.m_normal;
+ Node& n=*c.m_node;
+ Face& f=*c.m_face;
+ const btVector3 p=BaryEval( f.m_n[0]->m_x,
+ f.m_n[1]->m_x,
+ f.m_n[2]->m_x,
+ c.m_weights);
+ const btVector3 q=BaryEval( f.m_n[0]->m_q,
+ f.m_n[1]->m_q,
+ f.m_n[2]->m_q,
+ c.m_weights);
+ const btVector3 vr=(n.m_x-n.m_q)-(p-q);
+ btVector3 corr(0,0,0);
+ if(dot(vr,nr)<0)
{
- const btScalar j=c.m_margin-(dot(nr,n.m_x)-dot(nr,p));
- corr+=c.m_normal*j;
+ const btScalar j=c.m_margin-(dot(nr,n.m_x)-dot(nr,p));
+ corr+=c.m_normal*j;
}
- corr -= ProjectOnPlane(vr,nr)*c.m_friction;
- n.m_x += corr*c.m_cfm[0];
- f.m_n[0]->m_x -= corr*(c.m_cfm[1]*c.m_weights.x());
- f.m_n[1]->m_x -= corr*(c.m_cfm[1]*c.m_weights.y());
- f.m_n[2]->m_x -= corr*(c.m_cfm[1]*c.m_weights.z());
+ corr -= ProjectOnPlane(vr,nr)*c.m_friction;
+ n.m_x += corr*c.m_cfm[0];
+ f.m_n[0]->m_x -= corr*(c.m_cfm[1]*c.m_weights.x());
+ f.m_n[1]->m_x -= corr*(c.m_cfm[1]*c.m_weights.y());
+ f.m_n[2]->m_x -= corr*(c.m_cfm[1]*c.m_weights.z());
}
}
@@ -2522,107 +2584,114 @@ void btSoftBody::PSolve_Links(btSoftBody* psb,btScalar kst,btScalar ti)
//
void btSoftBody::VSolve_Links(btSoftBody* psb,btScalar kst)
{
-for(int i=0,ni=psb->m_links.size();i<ni;++i)
+ for(int i=0,ni=psb->m_links.size();i<ni;++i)
{
- Link& l=psb->m_links[i];
- Node** n=l.m_n;
- const btScalar j=-dot(l.m_c3,n[0]->m_v-n[1]->m_v)*l.m_c2*kst;
- n[0]->m_v+= l.m_c3*(j*n[0]->m_im);
- n[1]->m_v-= l.m_c3*(j*n[1]->m_im);
+ Link& l=psb->m_links[i];
+ Node** n=l.m_n;
+ const btScalar j=-dot(l.m_c3,n[0]->m_v-n[1]->m_v)*l.m_c2*kst;
+ n[0]->m_v+= l.m_c3*(j*n[0]->m_im);
+ n[1]->m_v-= l.m_c3*(j*n[1]->m_im);
}
}
//
btSoftBody::psolver_t btSoftBody::getSolver(ePSolver::_ solver)
{
-switch(solver)
+ switch(solver)
{
case ePSolver::Anchors: return(&btSoftBody::PSolve_Anchors);
case ePSolver::Linear: return(&btSoftBody::PSolve_Links);
case ePSolver::RContacts: return(&btSoftBody::PSolve_RContacts);
case ePSolver::SContacts: return(&btSoftBody::PSolve_SContacts);
}
-return(0);
+ return(0);
}
//
btSoftBody::vsolver_t btSoftBody::getSolver(eVSolver::_ solver)
{
-switch(solver)
+ switch(solver)
{
case eVSolver::Linear: return(&btSoftBody::VSolve_Links);
}
-return(0);
+ return(0);
}
//
void btSoftBody::defaultCollisionHandler(btCollisionObject* pco)
{
-switch(m_cfg.collisions&fCollision::RVSmask)
+ switch(m_cfg.collisions&fCollision::RVSmask)
{
case fCollision::SDF_RS:
{
- btSoftColliders::CollideSDF_RS docollide;
- btRigidBody* prb=btRigidBody::upcast(pco);
- const btTransform wtr=prb->getInterpolationWorldTransform();
- const btTransform ctr=prb->getWorldTransform();
- const btScalar timemargin=(wtr.getOrigin()-ctr.getOrigin()).length();
- const btScalar basemargin=getCollisionShape()->getMargin();
- btVector3 mins;
- btVector3 maxs;
- ATTRIBUTE_ALIGNED16(btDbvtVolume) volume;
- pco->getCollisionShape()->getAabb( pco->getInterpolationWorldTransform(),
- mins,
- maxs);
- volume=btDbvtVolume::FromMM(mins,maxs);
- volume.Expand(btVector3(basemargin,basemargin,basemargin));
- docollide.psb = this;
- docollide.prb = prb;
- docollide.dynmargin = basemargin+timemargin;
- docollide.stamargin = basemargin;
- btDbvt::collideTV(m_ndbvt.m_root,volume,docollide);
- }
- break;
+ btSoftColliders::CollideSDF_RS docollide;
+ btRigidBody* prb1=btRigidBody::upcast(pco);
+ btTransform wtr=prb1 ? prb1->getInterpolationWorldTransform() : pco->getWorldTransform();
+
+ const btTransform ctr=pco->getWorldTransform();
+ const btScalar timemargin=(wtr.getOrigin()-ctr.getOrigin()).length();
+ const btScalar basemargin=getCollisionShape()->getMargin();
+ btVector3 mins;
+ btVector3 maxs;
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) volume;
+ pco->getCollisionShape()->getAabb( pco->getInterpolationWorldTransform(),
+ mins,
+ maxs);
+ volume=btDbvtVolume::FromMM(mins,maxs);
+ volume.Expand(btVector3(basemargin,basemargin,basemargin));
+ docollide.psb = this;
+ docollide.m_colObj1 = pco;
+ docollide.m_rigidBody = prb1;
+
+ docollide.dynmargin = basemargin+timemargin;
+ docollide.stamargin = basemargin;
+ m_ndbvt.collideTV(m_ndbvt.m_root,volume,docollide);
+ }
+ break;
case fCollision::CL_RS:
{
- btSoftColliders::CollideCL_RS collider;
- collider.Process(this,btRigidBody::upcast(pco));
+ btSoftColliders::CollideCL_RS collider;
+ collider.Process(this,pco);
}
- break;
+ break;
}
}
//
void btSoftBody::defaultCollisionHandler(btSoftBody* psb)
{
-const int cf=m_cfg.collisions&psb->m_cfg.collisions;
-switch(cf&fCollision::SVSmask)
+ const int cf=m_cfg.collisions&psb->m_cfg.collisions;
+ switch(cf&fCollision::SVSmask)
{
case fCollision::CL_SS:
{
- btSoftColliders::CollideCL_SS docollide;
- docollide.Process(this,psb);
+ btSoftColliders::CollideCL_SS docollide;
+ docollide.Process(this,psb);
}
- break;
+ break;
case fCollision::VF_SS:
{
- btSoftColliders::CollideVF_SS docollide;
- /* common */
- docollide.mrg= getCollisionShape()->getMargin()+
- psb->getCollisionShape()->getMargin();
- /* psb0 nodes vs psb1 faces */
- docollide.psb[0]=this;
- docollide.psb[1]=psb;
- btDbvt::collideTT( docollide.psb[0]->m_ndbvt.m_root,
- docollide.psb[1]->m_fdbvt.m_root,
- docollide);
- /* psb1 nodes vs psb0 faces */
- docollide.psb[0]=psb;
- docollide.psb[1]=this;
- btDbvt::collideTT( docollide.psb[0]->m_ndbvt.m_root,
- docollide.psb[1]->m_fdbvt.m_root,
- docollide);
- }
- break;
+ //only self-collision for Cluster, not Vertex-Face yet
+ if (this!=psb)
+ {
+ btSoftColliders::CollideVF_SS docollide;
+ /* common */
+ docollide.mrg= getCollisionShape()->getMargin()+
+ psb->getCollisionShape()->getMargin();
+ /* psb0 nodes vs psb1 faces */
+ docollide.psb[0]=this;
+ docollide.psb[1]=psb;
+ docollide.psb[0]->m_ndbvt.collideTT( docollide.psb[0]->m_ndbvt.m_root,
+ docollide.psb[1]->m_fdbvt.m_root,
+ docollide);
+ /* psb1 nodes vs psb0 faces */
+ docollide.psb[0]=psb;
+ docollide.psb[1]=this;
+ docollide.psb[0]->m_ndbvt.collideTT( docollide.psb[0]->m_ndbvt.m_root,
+ docollide.psb[1]->m_fdbvt.m_root,
+ docollide);
+ }
+ }
+ break;
}
}
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBody.h b/extern/bullet2/src/BulletSoftBody/btSoftBody.h
index 743462d259a..a62c21883c8 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBody.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBody.h
@@ -18,7 +18,6 @@ subject to the following restrictions:
#define _BT_SOFT_BODY_H
#include "LinearMath/btAlignedObjectArray.h"
-#include "LinearMath/btPoint3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btIDebugDraw.h"
#include "BulletDynamics/Dynamics/btRigidBody.h"
@@ -45,7 +44,8 @@ struct btSoftBodyWorldInfo
};
-/// btSoftBody is work-in-progress
+///The btSoftBody is an class to simulate cloth and volumetric soft bodies.
+///There is two-way interaction between btSoftBody and btRigidBody/btCollisionObject.
class btSoftBody : public btCollisionObject
{
public:
@@ -64,13 +64,13 @@ public:
F_OneSided, ///Face normals are taken as it is
END
};};
-
+
///eVSolver : velocities solvers
struct eVSolver { enum _ {
Linear, ///Linear solver
END
};};
-
+
///ePSolver : positions solvers
struct ePSolver { enum _ {
Linear, ///Linear solver
@@ -79,7 +79,7 @@ public:
SContacts, ///Soft contacts solver
END
};};
-
+
///eSolverPresets
struct eSolverPresets { enum _ {
Positions,
@@ -87,7 +87,7 @@ public:
Default = Positions,
END
};};
-
+
///eFeature
struct eFeature { enum _ {
None,
@@ -96,20 +96,20 @@ public:
Face,
END
};};
-
+
typedef btAlignedObjectArray<eVSolver::_> tVSolverArray;
typedef btAlignedObjectArray<ePSolver::_> tPSolverArray;
-
+
//
// Flags
//
-
+
///fCollision
struct fCollision { enum _ {
RVSmask = 0x000f, ///Rigid versus soft mask
SDF_RS = 0x0001, ///SDF based rigid vs soft
CL_RS = 0x0002, ///Cluster vs convex rigid vs soft
-
+
SVSmask = 0x00f0, ///Rigid versus soft mask
VF_SS = 0x0010, ///Vertex vs face soft vs soft handling
CL_SS = 0x0020, ///Cluster vs cluster soft vs soft handling
@@ -117,7 +117,7 @@ public:
Default = SDF_RS,
END
};};
-
+
///fMaterial
struct fMaterial { enum _ {
DebugDraw = 0x0001, /// Enable debug draw
@@ -125,26 +125,26 @@ public:
Default = DebugDraw,
END
};};
-
+
//
// API Types
//
-
+
/* sRayCast */
struct sRayCast
{
btSoftBody* body; /// soft body
eFeature::_ feature; /// feature type
int index; /// feature index
- btScalar time; /// time of impact (rayorg+raydir*time)
+ btScalar fraction; /// time of impact fraction (rayorg+(rayto-rayfrom)*fraction)
};
-
+
/* ImplicitFn */
struct ImplicitFn
{
virtual btScalar Eval(const btVector3& x)=0;
};
-
+
//
// Internal types
//
@@ -155,7 +155,7 @@ public:
/* sCti is Softbody contact info */
struct sCti
{
- btRigidBody* m_body; /* Rigid body */
+ btCollisionObject* m_colObj; /* Rigid body */
btVector3 m_normal; /* Outward normal */
btScalar m_offset; /* Offset from origin */
};
@@ -182,7 +182,7 @@ public:
btScalar m_kVST; // Volume stiffness coefficient [0,1]
int m_flags; // Flags
};
-
+
/* Feature */
struct Feature : Element
{
@@ -293,12 +293,13 @@ public:
btVector3 m_lv;
btVector3 m_av;
btDbvtNode* m_leaf;
- btScalar m_ndamping;
- btScalar m_ldamping;
- btScalar m_adamping;
+ btScalar m_ndamping; /* Node damping */
+ btScalar m_ldamping; /* Linear damping */
+ btScalar m_adamping; /* Angular damping */
btScalar m_matching;
bool m_collide;
- Cluster() : m_leaf(0),m_ndamping(0),m_ldamping(0),m_adamping(0),m_matching(0) {}
+ int m_clusterIndex;
+ Cluster() : m_leaf(0),m_ndamping(0),m_ldamping(0),m_adamping(0),m_matching(0) {}
};
/* Impulse */
struct Impulse
@@ -309,109 +310,115 @@ public:
int m_asDrift:1;
Impulse() : m_velocity(0,0,0),m_drift(0,0,0),m_asVelocity(0),m_asDrift(0) {}
Impulse operator -() const
- {
+ {
Impulse i=*this;
i.m_velocity=-i.m_velocity;
i.m_drift=-i.m_drift;
return(i);
- }
+ }
Impulse operator*(btScalar x) const
- {
+ {
Impulse i=*this;
i.m_velocity*=x;
i.m_drift*=x;
return(i);
- }
+ }
};
/* Body */
struct Body
{
- Cluster* m_soft;
- btRigidBody* m_rigid;
- Body() : m_soft(0),m_rigid(0) {}
- Body(Cluster* p) : m_soft(p),m_rigid(0) {}
- Body(btRigidBody* p) : m_soft(0),m_rigid(p) {}
+ Cluster* m_soft;
+ btRigidBody* m_rigid;
+ btCollisionObject* m_collisionObject;
+
+ Body() : m_soft(0),m_rigid(0),m_collisionObject(0) {}
+ Body(Cluster* p) : m_soft(p),m_rigid(0),m_collisionObject(0) {}
+ Body(btCollisionObject* colObj) : m_soft(0),m_collisionObject(colObj)
+ {
+ m_rigid = btRigidBody::upcast(m_collisionObject);
+ }
+
void activate() const
- {
+ {
if(m_rigid) m_rigid->activate();
- }
+ }
const btMatrix3x3& invWorldInertia() const
- {
+ {
static const btMatrix3x3 iwi(0,0,0,0,0,0,0,0,0);
if(m_rigid) return(m_rigid->getInvInertiaTensorWorld());
if(m_soft) return(m_soft->m_invwi);
return(iwi);
- }
+ }
btScalar invMass() const
- {
+ {
if(m_rigid) return(m_rigid->getInvMass());
if(m_soft) return(m_soft->m_imass);
return(0);
- }
+ }
const btTransform& xform() const
- {
+ {
static const btTransform identity=btTransform::getIdentity();
- if(m_rigid) return(m_rigid->getInterpolationWorldTransform());
+ if(m_collisionObject) return(m_collisionObject->getInterpolationWorldTransform());
if(m_soft) return(m_soft->m_framexform);
return(identity);
- }
+ }
btVector3 linearVelocity() const
- {
+ {
if(m_rigid) return(m_rigid->getLinearVelocity());
if(m_soft) return(m_soft->m_lv);
return(btVector3(0,0,0));
- }
+ }
btVector3 angularVelocity(const btVector3& rpos) const
- {
+ {
if(m_rigid) return(cross(m_rigid->getAngularVelocity(),rpos));
if(m_soft) return(cross(m_soft->m_av,rpos));
return(btVector3(0,0,0));
- }
+ }
btVector3 angularVelocity() const
- {
+ {
if(m_rigid) return(m_rigid->getAngularVelocity());
if(m_soft) return(m_soft->m_av);
return(btVector3(0,0,0));
- }
+ }
btVector3 velocity(const btVector3& rpos) const
- {
+ {
return(linearVelocity()+angularVelocity(rpos));
- }
+ }
void applyVImpulse(const btVector3& impulse,const btVector3& rpos) const
- {
+ {
if(m_rigid) m_rigid->applyImpulse(impulse,rpos);
if(m_soft) btSoftBody::clusterVImpulse(m_soft,rpos,impulse);
- }
+ }
void applyDImpulse(const btVector3& impulse,const btVector3& rpos) const
- {
+ {
if(m_rigid) m_rigid->applyImpulse(impulse,rpos);
if(m_soft) btSoftBody::clusterDImpulse(m_soft,rpos,impulse);
- }
+ }
void applyImpulse(const Impulse& impulse,const btVector3& rpos) const
- {
+ {
if(impulse.m_asVelocity) applyVImpulse(impulse.m_velocity,rpos);
if(impulse.m_asDrift) applyDImpulse(impulse.m_drift,rpos);
- }
+ }
void applyVAImpulse(const btVector3& impulse) const
- {
+ {
if(m_rigid) m_rigid->applyTorqueImpulse(impulse);
if(m_soft) btSoftBody::clusterVAImpulse(m_soft,impulse);
- }
+ }
void applyDAImpulse(const btVector3& impulse) const
- {
+ {
if(m_rigid) m_rigid->applyTorqueImpulse(impulse);
if(m_soft) btSoftBody::clusterDAImpulse(m_soft,impulse);
- }
+ }
void applyAImpulse(const Impulse& impulse) const
- {
+ {
if(impulse.m_asVelocity) applyVAImpulse(impulse.m_velocity);
if(impulse.m_asDrift) applyDAImpulse(impulse.m_drift);
- }
+ }
void applyDCImpulse(const btVector3& impulse) const
- {
+ {
if(m_rigid) m_rigid->applyCentralImpulse(impulse);
if(m_soft) btSoftBody::clusterDCImpulse(m_soft,impulse);
- }
+ }
};
/* Joint */
struct Joint
@@ -419,15 +426,15 @@ public:
struct eType { enum _ {
Linear,
Angular,
- Contact,
+ Contact
};};
struct Specs
- {
- Specs() : erp(1),cfm(1),split(1) {}
+ {
+ Specs() : erp(1),cfm(1),split(1) {}
btScalar erp;
btScalar cfm;
btScalar split;
- };
+ };
Body m_bodies[2];
btVector3 m_refs[2];
btScalar m_cfm;
@@ -438,7 +445,7 @@ public:
btMatrix3x3 m_massmatrix;
bool m_delete;
virtual ~Joint() {}
- Joint() : m_delete(false) {}
+ Joint() : m_delete(false) {}
virtual void Prepare(btScalar dt,int iterations);
virtual void Solve(btScalar dt,btScalar sor)=0;
virtual void Terminate(btScalar dt)=0;
@@ -448,9 +455,9 @@ public:
struct LJoint : Joint
{
struct Specs : Joint::Specs
- {
+ {
btVector3 position;
- };
+ };
btVector3 m_rpos[2];
void Prepare(btScalar dt,int iterations);
void Solve(btScalar dt,btScalar sor);
@@ -461,17 +468,17 @@ public:
struct AJoint : Joint
{
struct IControl
- {
+ {
virtual void Prepare(AJoint*) {}
virtual btScalar Speed(AJoint*,btScalar current) { return(current); }
static IControl* Default() { static IControl def;return(&def); }
- };
+ };
struct Specs : Joint::Specs
- {
- Specs() : icontrol(IControl::Default()) {}
+ {
+ Specs() : icontrol(IControl::Default()) {}
btVector3 axis;
IControl* icontrol;
- };
+ };
btVector3 m_axis[2];
IControl* m_icontrol;
void Prepare(btScalar dt,int iterations);
@@ -534,23 +541,26 @@ public:
btScalar radmrg; // radial margin
btScalar updmrg; // Update margin
};
- /* RayCaster */
- struct RayCaster : btDbvt::ICollide
- {
- btVector3 o;
- btVector3 d;
- btScalar mint;
- Face* face;
- int tests;
- RayCaster(const btVector3& org,const btVector3& dir,btScalar mxt);
+ /// RayFromToCaster takes a ray from, ray to (instead of direction!)
+ struct RayFromToCaster : btDbvt::ICollide
+ {
+ btVector3 m_rayFrom;
+ btVector3 m_rayTo;
+ btVector3 m_rayNormalizedDirection;
+ btScalar m_mint;
+ Face* m_face;
+ int m_tests;
+ RayFromToCaster(const btVector3& rayFrom,const btVector3& rayTo,btScalar mxt);
void Process(const btDbvtNode* leaf);
- static inline btScalar rayTriangle(const btVector3& org,
- const btVector3& dir,
- const btVector3& a,
- const btVector3& b,
- const btVector3& c,
- btScalar maxt=SIMD_INFINITY);
- };
+
+ static inline btScalar rayFromToTriangle(const btVector3& rayFrom,
+ const btVector3& rayTo,
+ const btVector3& rayNormalizedDirection,
+ const btVector3& a,
+ const btVector3& b,
+ const btVector3& c,
+ btScalar maxt=SIMD_INFINITY);
+ };
//
// Typedef's
@@ -596,16 +606,19 @@ public:
btDbvt m_fdbvt; // Faces tree
btDbvt m_cdbvt; // Clusters tree
tClusterArray m_clusters; // Clusters
-
- btTransform m_initialWorldTransform; //used to attach constraints etc.
+
+ btAlignedObjectArray<bool>m_clusterConnectivity;//cluster connectivity, for self-collision
+
+ btTransform m_initialWorldTransform;
+
//
// Api
//
-
+
/* ctor */
btSoftBody( btSoftBodyWorldInfo* worldInfo,int node_count,
- const btVector3* x,
- const btScalar* m);
+ const btVector3* x,
+ const btScalar* m);
/* dtor */
virtual ~btSoftBody();
/* Check for existing link */
@@ -617,59 +630,60 @@ public:
return m_worldInfo;
}
+ ///@todo: avoid internal softbody shape hack and move collision code to collision library
virtual void setCollisionShape(btCollisionShape* collisionShape)
{
- //don't do anything, due to the internal shape hack: todo: fix this
+
}
bool checkLink( int node0,
int node1) const;
bool checkLink( const Node* node0,
- const Node* node1) const;
+ const Node* node1) const;
/* Check for existring face */
bool checkFace( int node0,
- int node1,
- int node2) const;
+ int node1,
+ int node2) const;
/* Append material */
Material* appendMaterial();
/* Append note */
void appendNote( const char* text,
- const btVector3& o,
- const btVector4& c=btVector4(1,0,0,0),
- Node* n0=0,
- Node* n1=0,
- Node* n2=0,
- Node* n3=0);
+ const btVector3& o,
+ const btVector4& c=btVector4(1,0,0,0),
+ Node* n0=0,
+ Node* n1=0,
+ Node* n2=0,
+ Node* n3=0);
void appendNote( const char* text,
- const btVector3& o,
- Node* feature);
+ const btVector3& o,
+ Node* feature);
void appendNote( const char* text,
- const btVector3& o,
- Link* feature);
+ const btVector3& o,
+ Link* feature);
void appendNote( const char* text,
- const btVector3& o,
- Face* feature);
+ const btVector3& o,
+ Face* feature);
/* Append node */
void appendNode( const btVector3& x,btScalar m);
/* Append link */
void appendLink(int model=-1,Material* mat=0);
void appendLink( int node0,
- int node1,
- Material* mat=0,
- bool bcheckexist=false);
+ int node1,
+ Material* mat=0,
+ bool bcheckexist=false);
void appendLink( Node* node0,
- Node* node1,
- Material* mat=0,
- bool bcheckexist=false);
+ Node* node1,
+ Material* mat=0,
+ bool bcheckexist=false);
/* Append face */
void appendFace(int model=-1,Material* mat=0);
void appendFace( int node0,
- int node1,
- int node2,
- Material* mat=0);
+ int node1,
+ int node2,
+ Material* mat=0);
/* Append anchor */
void appendAnchor( int node,
- btRigidBody* body,bool disableCollision);
+ btRigidBody* body, bool disableCollisionBetweenLinkedBodies=false);
/* Append linear joint */
void appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1);
void appendLinearJoint(const LJoint::Specs& specs,Body body=Body());
@@ -682,7 +696,7 @@ public:
void addForce( const btVector3& force);
/* Add force (or gravity) to a node of the body */
void addForce( const btVector3& force,
- int node);
+ int node);
/* Add velocity to the entire body */
void addVelocity( const btVector3& velocity);
@@ -691,17 +705,17 @@ public:
/* Add velocity to a node of the body */
void addVelocity( const btVector3& velocity,
- int node);
+ int node);
/* Set mass */
void setMass( int node,
- btScalar mass);
+ btScalar mass);
/* Get mass */
btScalar getMass( int node) const;
/* Get total mass */
btScalar getTotalMass() const;
/* Set total mass (weighted by previous masses) */
void setTotalMass( btScalar mass,
- bool fromfaces=false);
+ bool fromfaces=false);
/* Set total density */
void setTotalDensity(btScalar density);
/* Transform */
@@ -714,7 +728,7 @@ public:
void scale( const btVector3& scl);
/* Set current state as pose */
void setPose( bool bvolume,
- bool bframe);
+ bool bframe);
/* Return the volume */
btScalar getVolume() const;
/* Cluster count */
@@ -734,7 +748,7 @@ public:
static void clusterDCImpulse(Cluster* cluster,const btVector3& impulse);
/* Generate bending constraints based on distance in the adjency graph */
int generateBendingConstraints( int distance,
- Material* mat=0);
+ Material* mat=0);
/* Randomize constraints to reduce solver bias */
void randomizeConstraints();
/* Release clusters */
@@ -747,11 +761,11 @@ public:
/* CutLink */
bool cutLink(int node0,int node1,btScalar position);
bool cutLink(const Node* node0,const Node* node1,btScalar position);
- /* Ray casting */
- bool rayCast(const btVector3& org,
- const btVector3& dir,
- sRayCast& results,
- btScalar maxtime=SIMD_INFINITY);
+
+ ///Ray casting using rayFrom and rayTo in worldspace, (not direction!)
+ bool rayTest(const btVector3& rayFrom,
+ const btVector3& rayTo,
+ sRayCast& results);
/* Solver presets */
void setSolver(eSolverPresets::_ preset);
/* predictMotion */
@@ -769,11 +783,11 @@ public:
/* defaultCollisionHandlers */
void defaultCollisionHandler(btCollisionObject* pco);
void defaultCollisionHandler(btSoftBody* psb);
-
+
//
// Cast
//
-
+
static const btSoftBody* upcast(const btCollisionObject* colObj)
{
if (colObj->getInternalType()==CO_SOFT_BODY)
@@ -801,11 +815,12 @@ public:
//
void pointersToIndices();
void indicesToPointers(const int* map=0);
- int rayCast(const btVector3& org,const btVector3& dir,
- btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const;
+
+ int rayTest(const btVector3& rayFrom,const btVector3& rayTo,
+ btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const;
void initializeFaceTree();
btVector3 evaluateCom() const;
- bool checkContact(btRigidBody* prb,const btVector3& x,btScalar margin,btSoftBody::sCti& cti) const;
+ bool checkContact(btCollisionObject* colObj,const btVector3& x,btScalar margin,btSoftBody::sCti& cti) const;
void updateNormals();
void updateBounds();
void updatePose();
@@ -825,7 +840,7 @@ public:
static void VSolve_Links(btSoftBody* psb,btScalar kst);
static psolver_t getSolver(ePSolver::_ solver);
static vsolver_t getSolver(eVSolver::_ solver);
-
+
};
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp b/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp
index 61a57ea5da9..f334e15e0d3 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp
@@ -32,7 +32,7 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
#include "BulletSoftBody/btSoftBody.h"
-#define BT_SOFTBODY_TRIANGLE_EXTRUSION btScalar(0.3)//make this configurable
+#define BT_SOFTBODY_TRIANGLE_EXTRUSION btScalar(0.06)//make this configurable
btSoftBodyConcaveCollisionAlgorithm::btSoftBodyConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
: btCollisionAlgorithm(ci),
@@ -50,27 +50,27 @@ btSoftBodyConcaveCollisionAlgorithm::~btSoftBodyConcaveCollisionAlgorithm()
btSoftBodyTriangleCallback::btSoftBodyTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped):
- m_dispatcher(dispatcher),
- m_dispatchInfoPtr(0)
+m_dispatcher(dispatcher),
+m_dispatchInfoPtr(0)
{
m_softBody = (btSoftBody*) (isSwapped? body1:body0);
m_triBody = isSwapped? body0:body1;
-
- //
- // create the manifold from the dispatcher 'manifold pool'
- //
-// m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBody,m_triBody);
- clearCache();
+ //
+ // create the manifold from the dispatcher 'manifold pool'
+ //
+ // m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBody,m_triBody);
+
+ clearCache();
}
btSoftBodyTriangleCallback::~btSoftBodyTriangleCallback()
{
clearCache();
-// m_dispatcher->releaseManifold( m_manifoldPtr );
-
+ // m_dispatcher->releaseManifold( m_manifoldPtr );
+
}
-
+
void btSoftBodyTriangleCallback::clearCache()
{
@@ -83,18 +83,18 @@ void btSoftBodyTriangleCallback::clearCache()
delete tmp->m_childShape;
}
m_shapeCache.clear();
-};
+}
void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex)
{
- //just for debugging purposes
+ //just for debugging purposes
//printf("triangle %d",m_triangleCount++);
btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher1 = m_dispatcher;
- ///debug drawing of the overlapping triangles
+ ///debug drawing of the overlapping triangles
if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && m_dispatchInfoPtr->m_debugDraw->getDebugMode() > 0)
{
btVector3 color(255,255,0);
@@ -107,7 +107,7 @@ void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId,
btTriIndex triIndex(partId,triangleIndex,0);
btHashKey<btTriIndex> triKey(triIndex.getUid());
-
+
btTriIndex* shapeIndex = m_shapeCache[triKey];
if (shapeIndex)
{
@@ -116,13 +116,13 @@ void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId,
//copy over user pointers to temporary shape
tm->setUserPointer(ob->getRootCollisionShape()->getUserPointer());
-
+
btCollisionShape* tmpShape = ob->getCollisionShape();
ob->internalSetTemporaryCollisionShape( tm );
-
+
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_softBody,m_triBody,0);//m_manifoldPtr);
-
+
colAlgo->processCollision(m_softBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
colAlgo->~btCollisionAlgorithm();
ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
@@ -133,56 +133,56 @@ void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId,
//aabb filter is already applied!
//btCollisionObject* colObj = static_cast<btCollisionObject*>(m_convexProxy->m_clientObject);
-
-// if (m_softBody->getCollisionShape()->getShapeType()==
+
+ // if (m_softBody->getCollisionShape()->getShapeType()==
{
-// btVector3 other;
+ // btVector3 other;
btVector3 normal = (triangle[1]-triangle[0]).cross(triangle[2]-triangle[0]);
normal.normalize();
normal*= BT_SOFTBODY_TRIANGLE_EXTRUSION;
-// other=(triangle[0]+triangle[1]+triangle[2])*0.333333f;
-// other+=normal*22.f;
- btVector3 pts[6] = {triangle[0],
- triangle[1],
- triangle[2],
- triangle[0]-normal,
- triangle[1]-normal,
- triangle[2]-normal};
+ // other=(triangle[0]+triangle[1]+triangle[2])*0.333333f;
+ // other+=normal*22.f;
+ btVector3 pts[6] = {triangle[0]+normal,
+ triangle[1]+normal,
+ triangle[2]+normal,
+ triangle[0]-normal,
+ triangle[1]-normal,
+ triangle[2]-normal};
btConvexHullShape* tm = new btConvexHullShape(&pts[0].getX(),6);
-// btBU_Simplex1to4 tm(triangle[0],triangle[1],triangle[2],other);
-
+ // btBU_Simplex1to4 tm(triangle[0],triangle[1],triangle[2],other);
+
//btTriangleShape tm(triangle[0],triangle[1],triangle[2]);
- // tm.setMargin(m_collisionMarginTriangle);
-
+ // tm.setMargin(m_collisionMarginTriangle);
+
//copy over user pointers to temporary shape
tm->setUserPointer(ob->getRootCollisionShape()->getUserPointer());
-
+
btCollisionShape* tmpShape = ob->getCollisionShape();
ob->internalSetTemporaryCollisionShape( tm );
-
+
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_softBody,m_triBody,0);//m_manifoldPtr);
///this should use the btDispatcher, so the actual registered algorithm is used
// btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexBody,m_triBody);
//m_resultOut->setShapeIdentifiers(-1,-1,partId,triangleIndex);
- // cvxcvxalgo.setShapeIdentifiers(-1,-1,partId,triangleIndex);
-// cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
+ // cvxcvxalgo.setShapeIdentifiers(-1,-1,partId,triangleIndex);
+ // cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
colAlgo->processCollision(m_softBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
colAlgo->~btCollisionAlgorithm();
ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
-
-
+
+
ob->internalSetTemporaryCollisionShape( tmpShape );
triIndex.m_childShape = tm;
m_shapeCache.insert(triKey,triIndex);
}
-
+
}
@@ -194,7 +194,7 @@ void btSoftBodyTriangleCallback::setTimeStepAndCounters(btScalar collisionMargin
m_collisionMarginTriangle = collisionMarginTriangle+btScalar(BT_SOFTBODY_TRIANGLE_EXTRUSION);
m_resultOut = resultOut;
-
+
btVector3 aabbWorldSpaceMin,aabbWorldSpaceMax;
m_softBody->getAabb(aabbWorldSpaceMin,aabbWorldSpaceMax);
btVector3 halfExtents = (aabbWorldSpaceMax-aabbWorldSpaceMin)*btScalar(0.5);
@@ -217,8 +217,8 @@ void btSoftBodyConcaveCollisionAlgorithm::clearCache()
void btSoftBodyConcaveCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
-
-
+
+
btCollisionObject* convexBody = m_isSwapped ? body1 : body0;
btCollisionObject* triBody = m_isSwapped ? body0 : body1;
@@ -228,26 +228,26 @@ void btSoftBodyConcaveCollisionAlgorithm::processCollision (btCollisionObject* b
btCollisionObject* triOb = triBody;
btConcaveShape* concaveShape = static_cast<btConcaveShape*>( triOb->getCollisionShape());
-
- // if (convexBody->getCollisionShape()->isConvex())
+
+ // if (convexBody->getCollisionShape()->isConvex())
{
btScalar collisionMarginTriangle = concaveShape->getMargin();
-
-// resultOut->setPersistentManifold(m_btSoftBodyTriangleCallback.m_manifoldPtr);
+
+ // resultOut->setPersistentManifold(m_btSoftBodyTriangleCallback.m_manifoldPtr);
m_btSoftBodyTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,resultOut);
//Disable persistency. previously, some older algorithm calculated all contacts in one go, so you can clear it here.
//m_dispatcher->clearManifold(m_btSoftBodyTriangleCallback.m_manifoldPtr);
-// m_btSoftBodyTriangleCallback.m_manifoldPtr->setBodies(convexBody,triBody);
+ // m_btSoftBodyTriangleCallback.m_manifoldPtr->setBodies(convexBody,triBody);
concaveShape->processAllTriangles( &m_btSoftBodyTriangleCallback,m_btSoftBodyTriangleCallback.getAabbMin(),m_btSoftBodyTriangleCallback.getAabbMax());
-
- // resultOut->refreshContactPoints();
-
+
+ // resultOut->refreshContactPoints();
+
}
-
+
}
}
@@ -287,7 +287,7 @@ btScalar btSoftBodyConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionO
btScalar m_ccdSphereRadius;
btScalar m_hitFraction;
-
+
LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,btScalar ccdSphereRadius,btScalar hitFraction)
:m_ccdSphereFromTrans(from),
@@ -296,8 +296,8 @@ btScalar btSoftBodyConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionO
m_hitFraction(hitFraction)
{
}
-
-
+
+
virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
{
(void)partId;
@@ -327,9 +327,9 @@ btScalar btSoftBodyConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionO
};
-
-
+
+
if (triBody->getCollisionShape()->isConcave())
{
btVector3 rayAabbMin = convexFromLocal.getOrigin();
@@ -349,12 +349,12 @@ btScalar btSoftBodyConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionO
btCollisionObject* concavebody = triBody;
btConcaveShape* triangleMesh = (btConcaveShape*) concavebody->getCollisionShape();
-
+
if (triangleMesh)
{
triangleMesh->processAllTriangles(&raycastCallback,rayAabbMin,rayAabbMax);
}
-
+
if (raycastCallback.m_hitFraction < convexbody->getHitFraction())
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h b/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h
index 08ac3f11e20..a6ea33717bc 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h
@@ -35,7 +35,7 @@ struct btTriIndex
{
int m_PartIdTriangleIndex;
class btCollisionShape* m_childShape;
-
+
btTriIndex(int partId,int triangleIndex,btCollisionShape* shape)
{
m_PartIdTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex;
@@ -75,11 +75,11 @@ class btSoftBodyTriangleCallback : public btTriangleCallback
btScalar m_collisionMarginTriangle;
btHashMap<btHashKey<btTriIndex>,btTriIndex> m_shapeCache;
-
+
public:
-int m_triangleCount;
-
-// btPersistentManifold* m_manifoldPtr;
+ int m_triangleCount;
+
+ // btPersistentManifold* m_manifoldPtr;
btSoftBodyTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
@@ -88,7 +88,7 @@ int m_triangleCount;
virtual ~btSoftBodyTriangleCallback();
virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex);
-
+
void clearCache();
SIMD_FORCE_INLINE const btVector3& getAabbMin() const
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.cpp b/extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.cpp
index d9919967233..6ab93c16402 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.cpp
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.cpp
@@ -22,57 +22,57 @@ subject to the following restrictions:
//
static void drawVertex( btIDebugDraw* idraw,
- const btVector3& x,btScalar s,const btVector3& c)
- {
- idraw->drawLine(x-btVector3(s,0,0),x+btVector3(s,0,0),c);
- idraw->drawLine(x-btVector3(0,s,0),x+btVector3(0,s,0),c);
- idraw->drawLine(x-btVector3(0,0,s),x+btVector3(0,0,s),c);
- }
+ const btVector3& x,btScalar s,const btVector3& c)
+{
+ idraw->drawLine(x-btVector3(s,0,0),x+btVector3(s,0,0),c);
+ idraw->drawLine(x-btVector3(0,s,0),x+btVector3(0,s,0),c);
+ idraw->drawLine(x-btVector3(0,0,s),x+btVector3(0,0,s),c);
+}
//
static void drawBox( btIDebugDraw* idraw,
- const btVector3& mins,
- const btVector3& maxs,
- const btVector3& color)
+ const btVector3& mins,
+ const btVector3& maxs,
+ const btVector3& color)
{
-const btVector3 c[]={ btVector3(mins.x(),mins.y(),mins.z()),
- btVector3(maxs.x(),mins.y(),mins.z()),
- btVector3(maxs.x(),maxs.y(),mins.z()),
- btVector3(mins.x(),maxs.y(),mins.z()),
- btVector3(mins.x(),mins.y(),maxs.z()),
- btVector3(maxs.x(),mins.y(),maxs.z()),
- btVector3(maxs.x(),maxs.y(),maxs.z()),
- btVector3(mins.x(),maxs.y(),maxs.z())};
-idraw->drawLine(c[0],c[1],color);idraw->drawLine(c[1],c[2],color);
-idraw->drawLine(c[2],c[3],color);idraw->drawLine(c[3],c[0],color);
-idraw->drawLine(c[4],c[5],color);idraw->drawLine(c[5],c[6],color);
-idraw->drawLine(c[6],c[7],color);idraw->drawLine(c[7],c[4],color);
-idraw->drawLine(c[0],c[4],color);idraw->drawLine(c[1],c[5],color);
-idraw->drawLine(c[2],c[6],color);idraw->drawLine(c[3],c[7],color);
+ const btVector3 c[]={ btVector3(mins.x(),mins.y(),mins.z()),
+ btVector3(maxs.x(),mins.y(),mins.z()),
+ btVector3(maxs.x(),maxs.y(),mins.z()),
+ btVector3(mins.x(),maxs.y(),mins.z()),
+ btVector3(mins.x(),mins.y(),maxs.z()),
+ btVector3(maxs.x(),mins.y(),maxs.z()),
+ btVector3(maxs.x(),maxs.y(),maxs.z()),
+ btVector3(mins.x(),maxs.y(),maxs.z())};
+ idraw->drawLine(c[0],c[1],color);idraw->drawLine(c[1],c[2],color);
+ idraw->drawLine(c[2],c[3],color);idraw->drawLine(c[3],c[0],color);
+ idraw->drawLine(c[4],c[5],color);idraw->drawLine(c[5],c[6],color);
+ idraw->drawLine(c[6],c[7],color);idraw->drawLine(c[7],c[4],color);
+ idraw->drawLine(c[0],c[4],color);idraw->drawLine(c[1],c[5],color);
+ idraw->drawLine(c[2],c[6],color);idraw->drawLine(c[3],c[7],color);
}
//
static void drawTree( btIDebugDraw* idraw,
- const btDbvtNode* node,
- int depth,
- const btVector3& ncolor,
- const btVector3& lcolor,
- int mindepth,
- int maxdepth)
+ const btDbvtNode* node,
+ int depth,
+ const btVector3& ncolor,
+ const btVector3& lcolor,
+ int mindepth,
+ int maxdepth)
{
-if(node)
+ if(node)
{
- if(node->isinternal()&&((depth<maxdepth)||(maxdepth<0)))
+ if(node->isinternal()&&((depth<maxdepth)||(maxdepth<0)))
{
- drawTree(idraw,node->childs[0],depth+1,ncolor,lcolor,mindepth,maxdepth);
- drawTree(idraw,node->childs[1],depth+1,ncolor,lcolor,mindepth,maxdepth);
+ drawTree(idraw,node->childs[0],depth+1,ncolor,lcolor,mindepth,maxdepth);
+ drawTree(idraw,node->childs[1],depth+1,ncolor,lcolor,mindepth,maxdepth);
}
- if(depth>=mindepth)
+ if(depth>=mindepth)
{
- const btScalar scl=(btScalar)(node->isinternal()?1:1);
- const btVector3 mi=node->volume.Center()-node->volume.Extents()*scl;
- const btVector3 mx=node->volume.Center()+node->volume.Extents()*scl;
- drawBox(idraw,mi,mx,node->isleaf()?lcolor:ncolor);
+ const btScalar scl=(btScalar)(node->isinternal()?1:1);
+ const btVector3 mi=node->volume.Center()-node->volume.Extents()*scl;
+ const btVector3 mx=node->volume.Center()+node->volume.Extents()*scl;
+ drawBox(idraw,mi,mx,node->isleaf()?lcolor:ncolor);
}
}
}
@@ -81,25 +81,25 @@ if(node)
template <typename T>
static inline T sum(const btAlignedObjectArray<T>& items)
{
-T v;
-if(items.size())
+ T v;
+ if(items.size())
{
- v=items[0];
- for(int i=1,ni=items.size();i<ni;++i)
+ v=items[0];
+ for(int i=1,ni=items.size();i<ni;++i)
{
- v+=items[i];
+ v+=items[i];
}
}
-return(v);
+ return(v);
}
//
template <typename T,typename Q>
static inline void add(btAlignedObjectArray<T>& items,const Q& value)
{
-for(int i=0,ni=items.size();i<ni;++i)
+ for(int i=0,ni=items.size();i<ni;++i)
{
- items[i]+=value;
+ items[i]+=value;
}
}
@@ -107,9 +107,9 @@ for(int i=0,ni=items.size();i<ni;++i)
template <typename T,typename Q>
static inline void mul(btAlignedObjectArray<T>& items,const Q& value)
{
-for(int i=0,ni=items.size();i<ni;++i)
+ for(int i=0,ni=items.size();i<ni;++i)
{
- items[i]*=value;
+ items[i]*=value;
}
}
@@ -117,8 +117,8 @@ for(int i=0,ni=items.size();i<ni;++i)
template <typename T>
static inline T average(const btAlignedObjectArray<T>& items)
{
-const btScalar n=(btScalar)(items.size()>0?items.size():1);
-return(sum(items)/n);
+ const btScalar n=(btScalar)(items.size()>0?items.size():1);
+ return(sum(items)/n);
}
//
@@ -136,27 +136,27 @@ static inline btScalar tetravolume(const btVector3& x0,
//
#if 0
static btVector3 stresscolor(btScalar stress)
- {
+{
static const btVector3 spectrum[]= { btVector3(1,0,1),
- btVector3(0,0,1),
- btVector3(0,1,1),
- btVector3(0,1,0),
- btVector3(1,1,0),
- btVector3(1,0,0),
- btVector3(1,0,0)};
+ btVector3(0,0,1),
+ btVector3(0,1,1),
+ btVector3(0,1,0),
+ btVector3(1,1,0),
+ btVector3(1,0,0),
+ btVector3(1,0,0)};
static const int ncolors=sizeof(spectrum)/sizeof(spectrum[0])-1;
static const btScalar one=1;
stress=btMax<btScalar>(0,btMin<btScalar>(1,stress))*ncolors;
const int sel=(int)stress;
const btScalar frc=stress-sel;
return(spectrum[sel]+(spectrum[sel+1]-spectrum[sel])*frc);
- }
+}
#endif
//
void btSoftBodyHelpers::Draw( btSoftBody* psb,
- btIDebugDraw* idraw,
- int drawflags)
+ btIDebugDraw* idraw,
+ int drawflags)
{
const btScalar scl=(btScalar)0.1;
const btScalar nscl=scl*5;
@@ -251,29 +251,29 @@ void btSoftBodyHelpers::Draw( btSoftBody* psb,
const btVector3 x[]={f.m_n[0]->m_x,f.m_n[1]->m_x,f.m_n[2]->m_x};
const btVector3 c=(x[0]+x[1]+x[2])/3;
idraw->drawTriangle((x[0]-c)*scl+c,
- (x[1]-c)*scl+c,
- (x[2]-c)*scl+c,
- col,alp);
+ (x[1]-c)*scl+c,
+ (x[2]-c)*scl+c,
+ col,alp);
}
}
/* Clusters */
if(0!=(drawflags&fDrawFlags::Clusters))
- {
+ {
srand(1806);
for(i=0;i<psb->m_clusters.size();++i)
- {
+ {
if(psb->m_clusters[i]->m_collide)
- {
+ {
btVector3 color( rand()/(btScalar)RAND_MAX,
- rand()/(btScalar)RAND_MAX,
- rand()/(btScalar)RAND_MAX);
+ rand()/(btScalar)RAND_MAX,
+ rand()/(btScalar)RAND_MAX);
color=color.normalized()*0.75;
btAlignedObjectArray<btVector3> vertices;
vertices.resize(psb->m_clusters[i]->m_nodes.size());
for(j=0,nj=vertices.size();j<nj;++j)
- {
+ {
vertices[j]=psb->m_clusters[i]->m_nodes[j]->m_x;
- }
+ }
HullDesc hdsc(QF_TRIANGLES,vertices.size(),&vertices[0]);
HullResult hres;
HullLibrary hlib;
@@ -284,32 +284,32 @@ void btSoftBodyHelpers::Draw( btSoftBody* psb,
mul(hres.m_OutputVertices,(btScalar)1);
add(hres.m_OutputVertices,center);
for(j=0;j<(int)hres.mNumFaces;++j)
- {
+ {
const int idx[]={hres.m_Indices[j*3+0],hres.m_Indices[j*3+1],hres.m_Indices[j*3+2]};
idraw->drawTriangle(hres.m_OutputVertices[idx[0]],
- hres.m_OutputVertices[idx[1]],
- hres.m_OutputVertices[idx[2]],
- color,1);
- }
- hlib.ReleaseResult(hres);
+ hres.m_OutputVertices[idx[1]],
+ hres.m_OutputVertices[idx[2]],
+ color,1);
}
+ hlib.ReleaseResult(hres);
+ }
/* Velocities */
- #if 0
+#if 0
for(int j=0;j<psb->m_clusters[i].m_nodes.size();++j)
- {
+ {
const btSoftBody::Cluster& c=psb->m_clusters[i];
const btVector3 r=c.m_nodes[j]->m_x-c.m_com;
const btVector3 v=c.m_lv+cross(c.m_av,r);
idraw->drawLine(c.m_nodes[j]->m_x,c.m_nodes[j]->m_x+v,btVector3(1,0,0));
- }
- #endif
+ }
+#endif
/* Frame */
btSoftBody::Cluster& c=*psb->m_clusters[i];
idraw->drawLine(c.m_com,c.m_framexform*btVector3(10,0,0),btVector3(1,0,0));
idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,10,0),btVector3(0,1,0));
idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,0,10),btVector3(0,0,1));
- }
}
+ }
/* Notes */
if(0!=(drawflags&fDrawFlags::Notes))
{
@@ -318,9 +318,9 @@ void btSoftBodyHelpers::Draw( btSoftBody* psb,
const btSoftBody::Note& n=psb->m_notes[i];
btVector3 p=n.m_offset;
for(int j=0;j<n.m_rank;++j)
- {
+ {
p+=n.m_nodes[j]->m_x*n.m_coords[j];
- }
+ }
idraw->draw3dText(p,n.m_text);
}
}
@@ -333,33 +333,33 @@ void btSoftBodyHelpers::Draw( btSoftBody* psb,
/* Joints */
if(0!=(drawflags&fDrawFlags::Joints))
{
- for(i=0;i<psb->m_joints.size();++i)
+ for(i=0;i<psb->m_joints.size();++i)
{
- const btSoftBody::Joint* pj=psb->m_joints[i];
- switch(pj->Type())
+ const btSoftBody::Joint* pj=psb->m_joints[i];
+ switch(pj->Type())
{
case btSoftBody::Joint::eType::Linear:
{
- const btSoftBody::LJoint* pjl=(const btSoftBody::LJoint*)pj;
- const btVector3 a0=pj->m_bodies[0].xform()*pjl->m_refs[0];
- const btVector3 a1=pj->m_bodies[1].xform()*pjl->m_refs[1];
- idraw->drawLine(pj->m_bodies[0].xform().getOrigin(),a0,btVector3(1,1,0));
- idraw->drawLine(pj->m_bodies[1].xform().getOrigin(),a1,btVector3(0,1,1));
- drawVertex(idraw,a0,0.25,btVector3(1,1,0));
- drawVertex(idraw,a1,0.25,btVector3(0,1,1));
+ const btSoftBody::LJoint* pjl=(const btSoftBody::LJoint*)pj;
+ const btVector3 a0=pj->m_bodies[0].xform()*pjl->m_refs[0];
+ const btVector3 a1=pj->m_bodies[1].xform()*pjl->m_refs[1];
+ idraw->drawLine(pj->m_bodies[0].xform().getOrigin(),a0,btVector3(1,1,0));
+ idraw->drawLine(pj->m_bodies[1].xform().getOrigin(),a1,btVector3(0,1,1));
+ drawVertex(idraw,a0,0.25,btVector3(1,1,0));
+ drawVertex(idraw,a1,0.25,btVector3(0,1,1));
}
- break;
+ break;
case btSoftBody::Joint::eType::Angular:
{
- const btSoftBody::AJoint* pja=(const btSoftBody::AJoint*)pj;
- const btVector3 o0=pj->m_bodies[0].xform().getOrigin();
- const btVector3 o1=pj->m_bodies[1].xform().getOrigin();
- const btVector3 a0=pj->m_bodies[0].xform().getBasis()*pj->m_refs[0];
- const btVector3 a1=pj->m_bodies[1].xform().getBasis()*pj->m_refs[1];
- idraw->drawLine(o0,o0+a0*10,btVector3(1,1,0));
- idraw->drawLine(o0,o0+a1*10,btVector3(1,1,0));
- idraw->drawLine(o1,o1+a0*10,btVector3(0,1,1));
- idraw->drawLine(o1,o1+a1*10,btVector3(0,1,1));
+ const btSoftBody::AJoint* pja=(const btSoftBody::AJoint*)pj;
+ const btVector3 o0=pj->m_bodies[0].xform().getOrigin();
+ const btVector3 o1=pj->m_bodies[1].xform().getOrigin();
+ const btVector3 a0=pj->m_bodies[0].xform().getBasis()*pj->m_refs[0];
+ const btVector3 a1=pj->m_bodies[1].xform().getBasis()*pj->m_refs[1];
+ idraw->drawLine(o0,o0+a0*10,btVector3(1,1,0));
+ idraw->drawLine(o0,o0+a1*10,btVector3(1,1,0));
+ idraw->drawLine(o1,o1+a0*10,btVector3(0,1,1));
+ idraw->drawLine(o1,o1+a1*10,btVector3(0,1,1));
}
}
}
@@ -368,10 +368,10 @@ void btSoftBodyHelpers::Draw( btSoftBody* psb,
//
void btSoftBodyHelpers::DrawInfos( btSoftBody* psb,
- btIDebugDraw* idraw,
- bool masses,
- bool areas,
- bool /*stress*/)
+ btIDebugDraw* idraw,
+ bool masses,
+ bool areas,
+ bool /*stress*/)
{
for(int i=0;i<psb->m_nodes.size();++i)
{
@@ -394,34 +394,34 @@ void btSoftBodyHelpers::DrawInfos( btSoftBody* psb,
//
void btSoftBodyHelpers::DrawNodeTree( btSoftBody* psb,
- btIDebugDraw* idraw,
- int mindepth,
- int maxdepth)
+ btIDebugDraw* idraw,
+ int mindepth,
+ int maxdepth)
{
-drawTree(idraw,psb->m_ndbvt.m_root,0,btVector3(1,0,1),btVector3(1,1,1),mindepth,maxdepth);
+ drawTree(idraw,psb->m_ndbvt.m_root,0,btVector3(1,0,1),btVector3(1,1,1),mindepth,maxdepth);
}
//
void btSoftBodyHelpers::DrawFaceTree( btSoftBody* psb,
- btIDebugDraw* idraw,
- int mindepth,
- int maxdepth)
+ btIDebugDraw* idraw,
+ int mindepth,
+ int maxdepth)
{
-drawTree(idraw,psb->m_fdbvt.m_root,0,btVector3(0,1,0),btVector3(1,0,0),mindepth,maxdepth);
+ drawTree(idraw,psb->m_fdbvt.m_root,0,btVector3(0,1,0),btVector3(1,0,0),mindepth,maxdepth);
}
//
void btSoftBodyHelpers::DrawClusterTree( btSoftBody* psb,
- btIDebugDraw* idraw,
- int mindepth,
- int maxdepth)
+ btIDebugDraw* idraw,
+ int mindepth,
+ int maxdepth)
{
-drawTree(idraw,psb->m_cdbvt.m_root,0,btVector3(0,1,1),btVector3(1,0,0),mindepth,maxdepth);
+ drawTree(idraw,psb->m_cdbvt.m_root,0,btVector3(0,1,1),btVector3(1,0,0),mindepth,maxdepth);
}
//
void btSoftBodyHelpers::DrawFrame( btSoftBody* psb,
- btIDebugDraw* idraw)
+ btIDebugDraw* idraw)
{
if(psb->m_pose.m_bframe)
{
@@ -445,9 +445,9 @@ void btSoftBodyHelpers::DrawFrame( btSoftBody* psb,
//
btSoftBody* btSoftBodyHelpers::CreateRope( btSoftBodyWorldInfo& worldInfo, const btVector3& from,
- const btVector3& to,
- int res,
- int fixeds)
+ const btVector3& to,
+ int res,
+ int fixeds)
{
/* Create nodes */
const int r=res+2;
@@ -477,13 +477,13 @@ btSoftBody* btSoftBodyHelpers::CreateRope( btSoftBodyWorldInfo& worldInfo, cons
//
btSoftBody* btSoftBodyHelpers::CreatePatch(btSoftBodyWorldInfo& worldInfo,const btVector3& corner00,
- const btVector3& corner10,
- const btVector3& corner01,
- const btVector3& corner11,
- int resx,
- int resy,
- int fixeds,
- bool gendiags)
+ const btVector3& corner10,
+ const btVector3& corner01,
+ const btVector3& corner11,
+ int resx,
+ int resy,
+ int fixeds,
+ bool gendiags)
{
#define IDX(_x_,_y_) ((_y_)*rx+(_x_))
/* Create nodes */
@@ -553,9 +553,215 @@ btSoftBody* btSoftBodyHelpers::CreatePatch(btSoftBodyWorldInfo& worldInfo,const
}
//
+btSoftBody* btSoftBodyHelpers::CreatePatchUV(btSoftBodyWorldInfo& worldInfo,
+ const btVector3& corner00,
+ const btVector3& corner10,
+ const btVector3& corner01,
+ const btVector3& corner11,
+ int resx,
+ int resy,
+ int fixeds,
+ bool gendiags,
+ float* tex_coords)
+{
+
+ /*
+ *
+ * corners:
+ *
+ * [0][0] corner00 ------- corner01 [resx][0]
+ * | |
+ * | |
+ * [0][resy] corner10 -------- corner11 [resx][resy]
+ *
+ *
+ *
+ *
+ *
+ *
+ * "fixedgs" map:
+ *
+ * corner00 --> +1
+ * corner01 --> +2
+ * corner10 --> +4
+ * corner11 --> +8
+ * upper middle --> +16
+ * left middle --> +32
+ * right middle --> +64
+ * lower middle --> +128
+ * center --> +256
+ *
+ *
+ * tex_coords size (resx-1)*(resy-1)*12
+ *
+ *
+ *
+ * SINGLE QUAD INTERNALS
+ *
+ * 1) btSoftBody's nodes and links,
+ * diagonal link is optional ("gendiags")
+ *
+ *
+ * node00 ------ node01
+ * | .
+ * | .
+ * | .
+ * | .
+ * | .
+ * node10 node11
+ *
+ *
+ *
+ * 2) Faces:
+ * two triangles,
+ * UV Coordinates (hier example for single quad)
+ *
+ * (0,1) (0,1) (1,1)
+ * 1 |\ 3 \-----| 2
+ * | \ \ |
+ * | \ \ |
+ * | \ \ |
+ * | \ \ |
+ * 2 |-----\ 3 \| 1
+ * (0,0) (1,0) (1,0)
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+#define IDX(_x_,_y_) ((_y_)*rx+(_x_))
+ /* Create nodes */
+ if((resx<2)||(resy<2)) return(0);
+ const int rx=resx;
+ const int ry=resy;
+ const int tot=rx*ry;
+ btVector3* x=new btVector3[tot];
+ btScalar* m=new btScalar[tot];
+
+ int iy;
+
+ for(iy=0;iy<ry;++iy)
+ {
+ const btScalar ty=iy/(btScalar)(ry-1);
+ const btVector3 py0=lerp(corner00,corner01,ty);
+ const btVector3 py1=lerp(corner10,corner11,ty);
+ for(int ix=0;ix<rx;++ix)
+ {
+ const btScalar tx=ix/(btScalar)(rx-1);
+ x[IDX(ix,iy)]=lerp(py0,py1,tx);
+ m[IDX(ix,iy)]=1;
+ }
+ }
+ btSoftBody* psb=new btSoftBody(&worldInfo,tot,x,m);
+ if(fixeds&1) psb->setMass(IDX(0,0),0);
+ if(fixeds&2) psb->setMass(IDX(rx-1,0),0);
+ if(fixeds&4) psb->setMass(IDX(0,ry-1),0);
+ if(fixeds&8) psb->setMass(IDX(rx-1,ry-1),0);
+ if(fixeds&16) psb->setMass(IDX((rx-1)/2,0),0);
+ if(fixeds&32) psb->setMass(IDX(0,(ry-1)/2),0);
+ if(fixeds&64) psb->setMass(IDX(rx-1,(ry-1)/2),0);
+ if(fixeds&128) psb->setMass(IDX((rx-1)/2,ry-1),0);
+ if(fixeds&256) psb->setMass(IDX((rx-1)/2,(ry-1)/2),0);
+ delete[] x;
+ delete[] m;
+
+
+ int z = 0;
+ /* Create links and faces */
+ for(iy=0;iy<ry;++iy)
+ {
+ for(int ix=0;ix<rx;++ix)
+ {
+ const bool mdx=(ix+1)<rx;
+ const bool mdy=(iy+1)<ry;
+
+ int node00=IDX(ix,iy);
+ int node01=IDX(ix+1,iy);
+ int node10=IDX(ix,iy+1);
+ int node11=IDX(ix+1,iy+1);
+
+ if(mdx) psb->appendLink(node00,node01);
+ if(mdy) psb->appendLink(node00,node10);
+ if(mdx&&mdy)
+ {
+ psb->appendFace(node00,node10,node11);
+ if (tex_coords) {
+ tex_coords[z+0]=CalculateUV(resx,resy,ix,iy,0);
+ tex_coords[z+1]=CalculateUV(resx,resy,ix,iy,1);
+ tex_coords[z+2]=CalculateUV(resx,resy,ix,iy,0);
+ tex_coords[z+3]=CalculateUV(resx,resy,ix,iy,2);
+ tex_coords[z+4]=CalculateUV(resx,resy,ix,iy,3);
+ tex_coords[z+5]=CalculateUV(resx,resy,ix,iy,2);
+ }
+ psb->appendFace(node11,node01,node00);
+ if (tex_coords) {
+ tex_coords[z+6 ]=CalculateUV(resx,resy,ix,iy,3);
+ tex_coords[z+7 ]=CalculateUV(resx,resy,ix,iy,2);
+ tex_coords[z+8 ]=CalculateUV(resx,resy,ix,iy,3);
+ tex_coords[z+9 ]=CalculateUV(resx,resy,ix,iy,1);
+ tex_coords[z+10]=CalculateUV(resx,resy,ix,iy,0);
+ tex_coords[z+11]=CalculateUV(resx,resy,ix,iy,1);
+ }
+ if (gendiags) psb->appendLink(node00,node11);
+ z += 12;
+ }
+ }
+ }
+ /* Finished */
+#undef IDX
+ return(psb);
+}
+
+float btSoftBodyHelpers::CalculateUV(int resx,int resy,int ix,int iy,int id)
+{
+
+ /*
+ *
+ *
+ * node00 --- node01
+ * | |
+ * node10 --- node11
+ *
+ *
+ * ID map:
+ *
+ * node00 s --> 0
+ * node00 t --> 1
+ *
+ * node01 s --> 3
+ * node01 t --> 1
+ *
+ * node10 s --> 0
+ * node10 t --> 2
+ *
+ * node11 s --> 3
+ * node11 t --> 2
+ *
+ *
+ */
+
+ float tc=0.0f;
+ if (id == 0) {
+ tc = (1.0f/((resx-1))*ix);
+ }
+ else if (id==1) {
+ tc = (1.0f/((resy-1))*(resy-1-iy));
+ }
+ else if (id==2) {
+ tc = (1.0f/((resy-1))*(resy-1-iy-1));
+ }
+ else if (id==3) {
+ tc = (1.0f/((resx-1))*(ix+1));
+ }
+ return tc;
+}
+//
btSoftBody* btSoftBodyHelpers::CreateEllipsoid(btSoftBodyWorldInfo& worldInfo,const btVector3& center,
- const btVector3& radius,
- int res)
+ const btVector3& radius,
+ int res)
{
struct Hammersley
{
@@ -586,8 +792,8 @@ btSoftBody* btSoftBodyHelpers::CreateEllipsoid(btSoftBodyWorldInfo& worldInfo,c
//
btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBodyWorldInfo& worldInfo,const btScalar* vertices,
- const int* triangles,
- int ntriangles)
+ const int* triangles,
+ int ntriangles)
{
int maxidx=0;
int i,j,ni;
@@ -615,7 +821,7 @@ btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBodyWorldInfo& worldInfo
if(!chks[IDX(idx[j],idx[k])])
{
chks[IDX(idx[j],idx[k])]=true;
- chks[IDX(idx[k],idx[k])]=true;
+ chks[IDX(idx[k],idx[j])]=true;
psb->appendLink(idx[j],idx[k]);
}
}
@@ -628,7 +834,7 @@ btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBodyWorldInfo& worldInfo
//
btSoftBody* btSoftBodyHelpers::CreateFromConvexHull(btSoftBodyWorldInfo& worldInfo, const btVector3* vertices,
- int nvertices)
+ int nvertices)
{
HullDesc hdsc(QF_TRIANGLES,nvertices,vertices);
HullResult hres;
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.h b/extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.h
index e9c6cb20657..0e3b50397ee 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBodyHelpers.h
@@ -39,69 +39,81 @@ struct fDrawFlags { enum _ {
Joints = 0x1000,
/* presets */
Std = Links+Faces+Tetras+Anchors+Notes+Joints,
- StdTetra = Std-Faces+Tetras,
+ StdTetra = Std-Faces+Tetras
};};
struct btSoftBodyHelpers
{
/* Draw body */
static void Draw( btSoftBody* psb,
- btIDebugDraw* idraw,
- int drawflags=fDrawFlags::Std);
+ btIDebugDraw* idraw,
+ int drawflags=fDrawFlags::Std);
/* Draw body infos */
static void DrawInfos( btSoftBody* psb,
- btIDebugDraw* idraw,
- bool masses,
- bool areas,
- bool stress);
+ btIDebugDraw* idraw,
+ bool masses,
+ bool areas,
+ bool stress);
/* Draw node tree */
static void DrawNodeTree( btSoftBody* psb,
- btIDebugDraw* idraw,
- int mindepth=0,
- int maxdepth=-1);
+ btIDebugDraw* idraw,
+ int mindepth=0,
+ int maxdepth=-1);
/* Draw face tree */
static void DrawFaceTree( btSoftBody* psb,
- btIDebugDraw* idraw,
- int mindepth=0,
- int maxdepth=-1);
+ btIDebugDraw* idraw,
+ int mindepth=0,
+ int maxdepth=-1);
/* Draw cluster tree */
static void DrawClusterTree(btSoftBody* psb,
- btIDebugDraw* idraw,
- int mindepth=0,
- int maxdepth=-1);
+ btIDebugDraw* idraw,
+ int mindepth=0,
+ int maxdepth=-1);
/* Draw rigid frame */
static void DrawFrame( btSoftBody* psb,
- btIDebugDraw* idraw);
+ btIDebugDraw* idraw);
/* Create a rope */
static btSoftBody* CreateRope( btSoftBodyWorldInfo& worldInfo,
- const btVector3& from,
- const btVector3& to,
- int res,
- int fixeds);
+ const btVector3& from,
+ const btVector3& to,
+ int res,
+ int fixeds);
/* Create a patch */
static btSoftBody* CreatePatch(btSoftBodyWorldInfo& worldInfo,
- const btVector3& corner00,
- const btVector3& corner10,
- const btVector3& corner01,
- const btVector3& corner11,
- int resx,
- int resy,
- int fixeds,
- bool gendiags);
+ const btVector3& corner00,
+ const btVector3& corner10,
+ const btVector3& corner01,
+ const btVector3& corner11,
+ int resx,
+ int resy,
+ int fixeds,
+ bool gendiags);
+ /* Create a patch with UV Texture Coordinates */
+ static btSoftBody* CreatePatchUV(btSoftBodyWorldInfo& worldInfo,
+ const btVector3& corner00,
+ const btVector3& corner10,
+ const btVector3& corner01,
+ const btVector3& corner11,
+ int resx,
+ int resy,
+ int fixeds,
+ bool gendiags,
+ float* tex_coords=0);
+ static float CalculateUV(int resx,int resy,int ix,int iy,int id);
/* Create an ellipsoid */
static btSoftBody* CreateEllipsoid(btSoftBodyWorldInfo& worldInfo,
- const btVector3& center,
- const btVector3& radius,
- int res);
+ const btVector3& center,
+ const btVector3& radius,
+ int res);
/* Create from trimesh */
static btSoftBody* CreateFromTriMesh( btSoftBodyWorldInfo& worldInfo,
- const btScalar* vertices,
- const int* triangles,
- int ntriangles);
+ const btScalar* vertices,
+ const int* triangles,
+ int ntriangles);
/* Create from convex-hull */
static btSoftBody* CreateFromConvexHull( btSoftBodyWorldInfo& worldInfo,
- const btVector3* vertices,
- int nvertices);
+ const btVector3* vertices,
+ int nvertices);
};
#endif //SOFT_BODY_HELPERS_H
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBodyInternals.h b/extern/bullet2/src/BulletSoftBody/btSoftBodyInternals.h
index 8fcf633fecc..5f0f7d54318 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBodyInternals.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBodyInternals.h
@@ -31,14 +31,14 @@ subject to the following restrictions:
template <typename T>
struct btSymMatrix
{
- btSymMatrix() : dim(0) {}
- btSymMatrix(int n,const T& init=T()) { resize(n,init); }
-void resize(int n,const T& init=T()) { dim=n;store.resize((n*(n+1))/2,init); }
-int index(int c,int r) const { if(c>r) btSwap(c,r);btAssert(r<dim);return((r*(r+1))/2+c); }
-T& operator()(int c,int r) { return(store[index(c,r)]); }
-const T& operator()(int c,int r) const { return(store[index(c,r)]); }
-btAlignedObjectArray<T> store;
-int dim;
+ btSymMatrix() : dim(0) {}
+ btSymMatrix(int n,const T& init=T()) { resize(n,init); }
+ void resize(int n,const T& init=T()) { dim=n;store.resize((n*(n+1))/2,init); }
+ int index(int c,int r) const { if(c>r) btSwap(c,r);btAssert(r<dim);return((r*(r+1))/2+c); }
+ T& operator()(int c,int r) { return(store[index(c,r)]); }
+ const T& operator()(int c,int r) const { return(store[index(c,r)]); }
+ btAlignedObjectArray<T> store;
+ int dim;
};
//
@@ -48,10 +48,11 @@ class btSoftBodyCollisionShape : public btConcaveShape
{
public:
btSoftBody* m_body;
-
+
btSoftBodyCollisionShape(btSoftBody* backptr)
{
- m_body=backptr;
+ m_shapeType = SOFTBODY_SHAPE_PROXYTYPE;
+ m_body=backptr;
}
virtual ~btSoftBodyCollisionShape()
@@ -68,37 +69,34 @@ public:
///getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t.
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
{
- /* t should be identity, but better be safe than...fast? */
- const btVector3 mins=m_body->m_bounds[0];
- const btVector3 maxs=m_body->m_bounds[1];
- const btVector3 crns[]={t*btVector3(mins.x(),mins.y(),mins.z()),
- t*btVector3(maxs.x(),mins.y(),mins.z()),
- t*btVector3(maxs.x(),maxs.y(),mins.z()),
- t*btVector3(mins.x(),maxs.y(),mins.z()),
- t*btVector3(mins.x(),mins.y(),maxs.z()),
- t*btVector3(maxs.x(),mins.y(),maxs.z()),
- t*btVector3(maxs.x(),maxs.y(),maxs.z()),
- t*btVector3(mins.x(),maxs.y(),maxs.z())};
- aabbMin=aabbMax=crns[0];
- for(int i=1;i<8;++i)
+ /* t should be identity, but better be safe than...fast? */
+ const btVector3 mins=m_body->m_bounds[0];
+ const btVector3 maxs=m_body->m_bounds[1];
+ const btVector3 crns[]={t*btVector3(mins.x(),mins.y(),mins.z()),
+ t*btVector3(maxs.x(),mins.y(),mins.z()),
+ t*btVector3(maxs.x(),maxs.y(),mins.z()),
+ t*btVector3(mins.x(),maxs.y(),mins.z()),
+ t*btVector3(mins.x(),mins.y(),maxs.z()),
+ t*btVector3(maxs.x(),mins.y(),maxs.z()),
+ t*btVector3(maxs.x(),maxs.y(),maxs.z()),
+ t*btVector3(mins.x(),maxs.y(),maxs.z())};
+ aabbMin=aabbMax=crns[0];
+ for(int i=1;i<8;++i)
{
- aabbMin.setMin(crns[i]);
- aabbMax.setMax(crns[i]);
+ aabbMin.setMin(crns[i]);
+ aabbMax.setMax(crns[i]);
}
}
- virtual int getShapeType() const
- {
- return SOFTBODY_SHAPE_PROXYTYPE;
- }
+
virtual void setLocalScaling(const btVector3& /*scaling*/)
{
///na
}
virtual const btVector3& getLocalScaling() const
{
- static const btVector3 dummy(1,1,1);
- return dummy;
+ static const btVector3 dummy(1,1,1);
+ return dummy;
}
virtual void calculateLocalInertia(btScalar /*mass*/,btVector3& /*inertia*/) const
{
@@ -121,24 +119,24 @@ public:
const btSoftBody::Cluster* m_cluster;
btSoftClusterCollisionShape (const btSoftBody::Cluster* cluster) : m_cluster(cluster) { setMargin(0); }
-
-
+
+
virtual btVector3 localGetSupportingVertex(const btVector3& vec) const
- {
+ {
btSoftBody::Node* const * n=&m_cluster->m_nodes[0];
btScalar d=dot(vec,n[0]->m_x);
int j=0;
for(int i=1,ni=m_cluster->m_nodes.size();i<ni;++i)
- {
+ {
const btScalar k=dot(vec,n[i]->m_x);
if(k>d) { d=k;j=i; }
- }
- return(n[j]->m_x);
}
+ return(n[j]->m_x);
+ }
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const
- {
+ {
return(localGetSupportingVertex(vec));
- }
+ }
//notice that the vectors should be unit length
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
{}
@@ -151,7 +149,7 @@ public:
{}
virtual int getShapeType() const { return SOFTBODY_SHAPE_PROXYTYPE; }
-
+
//debugging
virtual const char* getName()const {return "SOFTCLUSTER";}
@@ -173,8 +171,8 @@ public:
template <typename T>
static inline void ZeroInitialize(T& value)
{
-static const T zerodummy;
-value=zerodummy;
+ static const T zerodummy;
+ value=zerodummy;
}
//
template <typename T>
@@ -194,23 +192,23 @@ static inline T InvLerp(const T& a,const T& b,btScalar t)
{ return((b+a*t-b*t)/(a*b)); }
//
static inline btMatrix3x3 Lerp( const btMatrix3x3& a,
- const btMatrix3x3& b,
- btScalar t)
-{
-btMatrix3x3 r;
-r[0]=Lerp(a[0],b[0],t);
-r[1]=Lerp(a[1],b[1],t);
-r[2]=Lerp(a[2],b[2],t);
-return(r);
+ const btMatrix3x3& b,
+ btScalar t)
+{
+ btMatrix3x3 r;
+ r[0]=Lerp(a[0],b[0],t);
+ r[1]=Lerp(a[1],b[1],t);
+ r[2]=Lerp(a[2],b[2],t);
+ return(r);
}
//
static inline btVector3 Clamp(const btVector3& v,btScalar maxlength)
{
-const btScalar sql=v.length2();
-if(sql>(maxlength*maxlength))
- return((v*maxlength)/btSqrt(sql));
+ const btScalar sql=v.length2();
+ if(sql>(maxlength*maxlength))
+ return((v*maxlength)/btSqrt(sql));
else
- return(v);
+ return(v);
}
//
template <typename T>
@@ -235,8 +233,8 @@ static inline bool SameSign(const T& x,const T& y)
//
static inline btScalar ClusterMetric(const btVector3& x,const btVector3& y)
{
-const btVector3 d=x-y;
-return(btFabs(d[0])+btFabs(d[1])+btFabs(d[2]));
+ const btVector3 d=x-y;
+ return(btFabs(d[0])+btFabs(d[1])+btFabs(d[2]));
}
//
static inline btMatrix3x3 ScaleAlongAxis(const btVector3& a,btScalar s)
@@ -273,7 +271,7 @@ static inline btMatrix3x3 Diagonal(btScalar x)
}
//
static inline btMatrix3x3 Add(const btMatrix3x3& a,
- const btMatrix3x3& b)
+ const btMatrix3x3& b)
{
btMatrix3x3 r;
for(int i=0;i<3;++i) r[i]=a[i]+b[i];
@@ -281,7 +279,7 @@ static inline btMatrix3x3 Add(const btMatrix3x3& a,
}
//
static inline btMatrix3x3 Sub(const btMatrix3x3& a,
- const btMatrix3x3& b)
+ const btMatrix3x3& b)
{
btMatrix3x3 r;
for(int i=0;i<3;++i) r[i]=a[i]-b[i];
@@ -289,7 +287,7 @@ static inline btMatrix3x3 Sub(const btMatrix3x3& a,
}
//
static inline btMatrix3x3 Mul(const btMatrix3x3& a,
- btScalar b)
+ btScalar b)
{
btMatrix3x3 r;
for(int i=0;i<3;++i) r[i]=a[i]*b;
@@ -298,9 +296,9 @@ static inline btMatrix3x3 Mul(const btMatrix3x3& a,
//
static inline void Orthogonalize(btMatrix3x3& m)
{
-m[2]=cross(m[0],m[1]).normalized();
-m[1]=cross(m[2],m[0]).normalized();
-m[0]=cross(m[1],m[2]).normalized();
+ m[2]=cross(m[0],m[1]).normalized();
+ m[1]=cross(m[2],m[0]).normalized();
+ m[0]=cross(m[1],m[2]).normalized();
}
//
static inline btMatrix3x3 MassMatrix(btScalar im,const btMatrix3x3& iwi,const btVector3& r)
@@ -311,90 +309,90 @@ static inline btMatrix3x3 MassMatrix(btScalar im,const btMatrix3x3& iwi,const bt
//
static inline btMatrix3x3 ImpulseMatrix( btScalar dt,
- btScalar ima,
- btScalar imb,
- const btMatrix3x3& iwi,
- const btVector3& r)
+ btScalar ima,
+ btScalar imb,
+ const btMatrix3x3& iwi,
+ const btVector3& r)
{
return(Diagonal(1/dt)*Add(Diagonal(ima),MassMatrix(imb,iwi,r)).inverse());
}
//
static inline btMatrix3x3 ImpulseMatrix( btScalar ima,const btMatrix3x3& iia,const btVector3& ra,
- btScalar imb,const btMatrix3x3& iib,const btVector3& rb)
+ btScalar imb,const btMatrix3x3& iib,const btVector3& rb)
{
-return(Add(MassMatrix(ima,iia,ra),MassMatrix(imb,iib,rb)).inverse());
+ return(Add(MassMatrix(ima,iia,ra),MassMatrix(imb,iib,rb)).inverse());
}
//
static inline btMatrix3x3 AngularImpulseMatrix( const btMatrix3x3& iia,
- const btMatrix3x3& iib)
+ const btMatrix3x3& iib)
{
-return(Add(iia,iib).inverse());
+ return(Add(iia,iib).inverse());
}
//
static inline btVector3 ProjectOnAxis( const btVector3& v,
- const btVector3& a)
+ const btVector3& a)
{
return(a*dot(v,a));
}
//
static inline btVector3 ProjectOnPlane( const btVector3& v,
- const btVector3& a)
+ const btVector3& a)
{
return(v-ProjectOnAxis(v,a));
}
//
static inline void ProjectOrigin( const btVector3& a,
- const btVector3& b,
- btVector3& prj,
- btScalar& sqd)
+ const btVector3& b,
+ btVector3& prj,
+ btScalar& sqd)
{
-const btVector3 d=b-a;
-const btScalar m2=d.length2();
-if(m2>SIMD_EPSILON)
+ const btVector3 d=b-a;
+ const btScalar m2=d.length2();
+ if(m2>SIMD_EPSILON)
{
- const btScalar t=Clamp<btScalar>(-dot(a,d)/m2,0,1);
- const btVector3 p=a+d*t;
- const btScalar l2=p.length2();
- if(l2<sqd)
+ const btScalar t=Clamp<btScalar>(-dot(a,d)/m2,0,1);
+ const btVector3 p=a+d*t;
+ const btScalar l2=p.length2();
+ if(l2<sqd)
{
- prj=p;
- sqd=l2;
+ prj=p;
+ sqd=l2;
}
}
}
//
static inline void ProjectOrigin( const btVector3& a,
- const btVector3& b,
- const btVector3& c,
- btVector3& prj,
- btScalar& sqd)
-{
-const btVector3& q=cross(b-a,c-a);
-const btScalar m2=q.length2();
-if(m2>SIMD_EPSILON)
+ const btVector3& b,
+ const btVector3& c,
+ btVector3& prj,
+ btScalar& sqd)
+{
+ const btVector3& q=cross(b-a,c-a);
+ const btScalar m2=q.length2();
+ if(m2>SIMD_EPSILON)
{
- const btVector3 n=q/btSqrt(m2);
- const btScalar k=dot(a,n);
- const btScalar k2=k*k;
- if(k2<sqd)
+ const btVector3 n=q/btSqrt(m2);
+ const btScalar k=dot(a,n);
+ const btScalar k2=k*k;
+ if(k2<sqd)
{
- const btVector3 p=n*k;
- if( (dot(cross(a-p,b-p),q)>0)&&
- (dot(cross(b-p,c-p),q)>0)&&
- (dot(cross(c-p,a-p),q)>0))
+ const btVector3 p=n*k;
+ if( (dot(cross(a-p,b-p),q)>0)&&
+ (dot(cross(b-p,c-p),q)>0)&&
+ (dot(cross(c-p,a-p),q)>0))
{
- prj=p;
- sqd=k2;
+ prj=p;
+ sqd=k2;
}
else
{
- ProjectOrigin(a,b,prj,sqd);
- ProjectOrigin(b,c,prj,sqd);
- ProjectOrigin(c,a,prj,sqd);
+ ProjectOrigin(a,b,prj,sqd);
+ ProjectOrigin(b,c,prj,sqd);
+ ProjectOrigin(c,a,prj,sqd);
}
}
}
@@ -403,53 +401,53 @@ if(m2>SIMD_EPSILON)
//
template <typename T>
static inline T BaryEval( const T& a,
- const T& b,
- const T& c,
- const btVector3& coord)
+ const T& b,
+ const T& c,
+ const btVector3& coord)
{
return(a*coord.x()+b*coord.y()+c*coord.z());
}
//
static inline btVector3 BaryCoord( const btVector3& a,
- const btVector3& b,
- const btVector3& c,
- const btVector3& p)
-{
-const btScalar w[]={ cross(a-p,b-p).length(),
- cross(b-p,c-p).length(),
- cross(c-p,a-p).length()};
-const btScalar isum=1/(w[0]+w[1]+w[2]);
-return(btVector3(w[1]*isum,w[2]*isum,w[0]*isum));
+ const btVector3& b,
+ const btVector3& c,
+ const btVector3& p)
+{
+ const btScalar w[]={ cross(a-p,b-p).length(),
+ cross(b-p,c-p).length(),
+ cross(c-p,a-p).length()};
+ const btScalar isum=1/(w[0]+w[1]+w[2]);
+ return(btVector3(w[1]*isum,w[2]*isum,w[0]*isum));
}
//
static btScalar ImplicitSolve( btSoftBody::ImplicitFn* fn,
- const btVector3& a,
- const btVector3& b,
- const btScalar accuracy,
- const int maxiterations=256)
-{
-btScalar span[2]={0,1};
-btScalar values[2]={fn->Eval(a),fn->Eval(b)};
-if(values[0]>values[1])
+ const btVector3& a,
+ const btVector3& b,
+ const btScalar accuracy,
+ const int maxiterations=256)
+{
+ btScalar span[2]={0,1};
+ btScalar values[2]={fn->Eval(a),fn->Eval(b)};
+ if(values[0]>values[1])
{
- btSwap(span[0],span[1]);
- btSwap(values[0],values[1]);
+ btSwap(span[0],span[1]);
+ btSwap(values[0],values[1]);
}
-if(values[0]>-accuracy) return(-1);
-if(values[1]<+accuracy) return(-1);
-for(int i=0;i<maxiterations;++i)
+ if(values[0]>-accuracy) return(-1);
+ if(values[1]<+accuracy) return(-1);
+ for(int i=0;i<maxiterations;++i)
{
- const btScalar t=Lerp(span[0],span[1],values[0]/(values[0]-values[1]));
- const btScalar v=fn->Eval(Lerp(a,b,t));
- if((t<=0)||(t>=1)) break;
- if(btFabs(v)<accuracy) return(t);
- if(v<0)
+ const btScalar t=Lerp(span[0],span[1],values[0]/(values[0]-values[1]));
+ const btScalar v=fn->Eval(Lerp(a,b,t));
+ if((t<=0)||(t>=1)) break;
+ if(btFabs(v)<accuracy) return(t);
+ if(v<0)
{ span[0]=t;values[0]=v; }
else
{ span[1]=t;values[1]=v; }
}
-return(-1);
+ return(-1);
}
//
@@ -464,26 +462,26 @@ static inline btVector3 NormalizeAny(const btVector3& v)
//
static inline btDbvtVolume VolumeOf( const btSoftBody::Face& f,
- btScalar margin)
-{
-const btVector3* pts[]={ &f.m_n[0]->m_x,
- &f.m_n[1]->m_x,
- &f.m_n[2]->m_x};
-btDbvtVolume vol=btDbvtVolume::FromPoints(pts,3);
-vol.Expand(btVector3(margin,margin,margin));
-return(vol);
+ btScalar margin)
+{
+ const btVector3* pts[]={ &f.m_n[0]->m_x,
+ &f.m_n[1]->m_x,
+ &f.m_n[2]->m_x};
+ btDbvtVolume vol=btDbvtVolume::FromPoints(pts,3);
+ vol.Expand(btVector3(margin,margin,margin));
+ return(vol);
}
//
static inline btVector3 CenterOf( const btSoftBody::Face& f)
{
-return((f.m_n[0]->m_x+f.m_n[1]->m_x+f.m_n[2]->m_x)/3);
+ return((f.m_n[0]->m_x+f.m_n[1]->m_x+f.m_n[2]->m_x)/3);
}
//
static inline btScalar AreaOf( const btVector3& x0,
- const btVector3& x1,
- const btVector3& x2)
+ const btVector3& x1,
+ const btVector3& x2)
{
const btVector3 a=x1-x0;
const btVector3 b=x2-x0;
@@ -494,9 +492,9 @@ static inline btScalar AreaOf( const btVector3& x0,
//
static inline btScalar VolumeOf( const btVector3& x0,
- const btVector3& x1,
- const btVector3& x2,
- const btVector3& x3)
+ const btVector3& x1,
+ const btVector3& x2,
+ const btVector3& x3)
{
const btVector3 a=x1-x0;
const btVector3 b=x2-x0;
@@ -506,8 +504,8 @@ static inline btScalar VolumeOf( const btVector3& x0,
//
static void EvaluateMedium( const btSoftBodyWorldInfo* wfi,
- const btVector3& x,
- btSoftBody::sMedium& medium)
+ const btVector3& x,
+ btSoftBody::sMedium& medium)
{
medium.m_velocity = btVector3(0,0,0);
medium.m_pressure = 0;
@@ -525,8 +523,8 @@ static void EvaluateMedium( const btSoftBodyWorldInfo* wfi,
//
static inline void ApplyClampedForce( btSoftBody::Node& n,
- const btVector3& f,
- btScalar dt)
+ const btVector3& f,
+ btScalar dt)
{
const btScalar dtim=dt*n.m_im;
if((f*dtim).length2()>n.m_v.length2())
@@ -541,13 +539,13 @@ static inline void ApplyClampedForce( btSoftBody::Node& n,
//
static inline int MatchEdge( const btSoftBody::Node* a,
- const btSoftBody::Node* b,
- const btSoftBody::Node* ma,
- const btSoftBody::Node* mb)
+ const btSoftBody::Node* b,
+ const btSoftBody::Node* ma,
+ const btSoftBody::Node* mb)
{
-if((a==ma)&&(b==mb)) return(0);
-if((a==mb)&&(b==ma)) return(1);
-return(-1);
+ if((a==ma)&&(b==mb)) return(0);
+ if((a==mb)&&(b==ma)) return(1);
+ return(-1);
}
//
@@ -557,56 +555,56 @@ return(-1);
//
struct btEigen
{
-static int system(btMatrix3x3& a,btMatrix3x3* vectors,btVector3* values=0)
+ static int system(btMatrix3x3& a,btMatrix3x3* vectors,btVector3* values=0)
{
- static const int maxiterations=16;
- static const btScalar accuracy=(btScalar)0.0001;
- btMatrix3x3& v=*vectors;
- int iterations=0;
- vectors->setIdentity();
- do {
- int p=0,q=1;
- if(btFabs(a[p][q])<btFabs(a[0][2])) { p=0;q=2; }
- if(btFabs(a[p][q])<btFabs(a[1][2])) { p=1;q=2; }
- if(btFabs(a[p][q])>accuracy)
+ static const int maxiterations=16;
+ static const btScalar accuracy=(btScalar)0.0001;
+ btMatrix3x3& v=*vectors;
+ int iterations=0;
+ vectors->setIdentity();
+ do {
+ int p=0,q=1;
+ if(btFabs(a[p][q])<btFabs(a[0][2])) { p=0;q=2; }
+ if(btFabs(a[p][q])<btFabs(a[1][2])) { p=1;q=2; }
+ if(btFabs(a[p][q])>accuracy)
{
- const btScalar w=(a[q][q]-a[p][p])/(2*a[p][q]);
- const btScalar z=btFabs(w);
- const btScalar t=w/(z*(btSqrt(1+w*w)+z));
- if(t==t)/* [WARNING] let hope that one does not get thrown aways by some compilers... */
+ const btScalar w=(a[q][q]-a[p][p])/(2*a[p][q]);
+ const btScalar z=btFabs(w);
+ const btScalar t=w/(z*(btSqrt(1+w*w)+z));
+ if(t==t)/* [WARNING] let hope that one does not get thrown aways by some compilers... */
{
- const btScalar c=1/btSqrt(t*t+1);
- const btScalar s=c*t;
- mulPQ(a,c,s,p,q);
- mulTPQ(a,c,s,p,q);
- mulPQ(v,c,s,p,q);
+ const btScalar c=1/btSqrt(t*t+1);
+ const btScalar s=c*t;
+ mulPQ(a,c,s,p,q);
+ mulTPQ(a,c,s,p,q);
+ mulPQ(v,c,s,p,q);
} else break;
} else break;
} while((++iterations)<maxiterations);
- if(values)
+ if(values)
{
- *values=btVector3(a[0][0],a[1][1],a[2][2]);
+ *values=btVector3(a[0][0],a[1][1],a[2][2]);
}
- return(iterations);
+ return(iterations);
}
private:
-static inline void mulTPQ(btMatrix3x3& a,btScalar c,btScalar s,int p,int q)
+ static inline void mulTPQ(btMatrix3x3& a,btScalar c,btScalar s,int p,int q)
{
- const btScalar m[2][3]={ {a[p][0],a[p][1],a[p][2]},
- {a[q][0],a[q][1],a[q][2]}};
- int i;
+ const btScalar m[2][3]={ {a[p][0],a[p][1],a[p][2]},
+ {a[q][0],a[q][1],a[q][2]}};
+ int i;
- for(i=0;i<3;++i) a[p][i]=c*m[0][i]-s*m[1][i];
- for(i=0;i<3;++i) a[q][i]=c*m[1][i]+s*m[0][i];
+ for(i=0;i<3;++i) a[p][i]=c*m[0][i]-s*m[1][i];
+ for(i=0;i<3;++i) a[q][i]=c*m[1][i]+s*m[0][i];
}
-static inline void mulPQ(btMatrix3x3& a,btScalar c,btScalar s,int p,int q)
+ static inline void mulPQ(btMatrix3x3& a,btScalar c,btScalar s,int p,int q)
{
- const btScalar m[2][3]={ {a[0][p],a[1][p],a[2][p]},
- {a[0][q],a[1][q],a[2][q]}};
- int i;
+ const btScalar m[2][3]={ {a[0][p],a[1][p],a[2][p]},
+ {a[0][q],a[1][q],a[2][q]}};
+ int i;
- for(i=0;i<3;++i) a[i][p]=c*m[0][i]-s*m[1][i];
- for(i=0;i<3;++i) a[i][q]=c*m[1][i]+s*m[0][i];
+ for(i=0;i<3;++i) a[i][p]=c*m[0][i]-s*m[1][i];
+ for(i=0;i<3;++i) a[i][q]=c*m[1][i]+s*m[0][i];
}
};
@@ -641,7 +639,7 @@ static inline int PolarDecompose( const btMatrix3x3& m,btMatrix3x3& q,btMatrix
q.setIdentity();
s.setIdentity();
}
-return(i);
+ return(i);
}
//
@@ -654,54 +652,54 @@ struct btSoftColliders
//
struct ClusterBase : btDbvt::ICollide
{
- btScalar erp;
- btScalar idt;
- btScalar margin;
- btScalar friction;
- btScalar threshold;
- ClusterBase()
+ btScalar erp;
+ btScalar idt;
+ btScalar margin;
+ btScalar friction;
+ btScalar threshold;
+ ClusterBase()
{
- erp =(btScalar)1;
- idt =0;
- margin =0;
- friction =0;
- threshold =(btScalar)0;
+ erp =(btScalar)1;
+ idt =0;
+ margin =0;
+ friction =0;
+ threshold =(btScalar)0;
}
- bool SolveContact( const btGjkEpaSolver2::sResults& res,
- btSoftBody::Body ba,btSoftBody::Body bb,
- btSoftBody::CJoint& joint)
+ bool SolveContact( const btGjkEpaSolver2::sResults& res,
+ btSoftBody::Body ba,btSoftBody::Body bb,
+ btSoftBody::CJoint& joint)
{
- if(res.distance<margin)
+ if(res.distance<margin)
{
- const btVector3 ra=res.witnesses[0]-ba.xform().getOrigin();
- const btVector3 rb=res.witnesses[1]-bb.xform().getOrigin();
- const btVector3 va=ba.velocity(ra);
- const btVector3 vb=bb.velocity(rb);
- const btVector3 vrel=va-vb;
- const btScalar rvac=dot(vrel,res.normal);
- const btScalar depth=res.distance-margin;
- const btVector3 iv=res.normal*rvac;
- const btVector3 fv=vrel-iv;
- joint.m_bodies[0] = ba;
- joint.m_bodies[1] = bb;
- joint.m_refs[0] = ra*ba.xform().getBasis();
- joint.m_refs[1] = rb*bb.xform().getBasis();
- joint.m_rpos[0] = ra;
- joint.m_rpos[1] = rb;
- joint.m_cfm = 1;
- joint.m_erp = 1;
- joint.m_life = 0;
- joint.m_maxlife = 0;
- joint.m_split = 1;
- joint.m_drift = depth*res.normal;
- joint.m_normal = res.normal;
- joint.m_delete = false;
- joint.m_friction = fv.length2()<(-rvac*friction)?1:friction;
- joint.m_massmatrix = ImpulseMatrix( ba.invMass(),ba.invWorldInertia(),joint.m_rpos[0],
- bb.invMass(),bb.invWorldInertia(),joint.m_rpos[1]);
- return(true);
+ const btVector3 ra=res.witnesses[0]-ba.xform().getOrigin();
+ const btVector3 rb=res.witnesses[1]-bb.xform().getOrigin();
+ const btVector3 va=ba.velocity(ra);
+ const btVector3 vb=bb.velocity(rb);
+ const btVector3 vrel=va-vb;
+ const btScalar rvac=dot(vrel,res.normal);
+ const btScalar depth=res.distance-margin;
+ const btVector3 iv=res.normal*rvac;
+ const btVector3 fv=vrel-iv;
+ joint.m_bodies[0] = ba;
+ joint.m_bodies[1] = bb;
+ joint.m_refs[0] = ra*ba.xform().getBasis();
+ joint.m_refs[1] = rb*bb.xform().getBasis();
+ joint.m_rpos[0] = ra;
+ joint.m_rpos[1] = rb;
+ joint.m_cfm = 1;
+ joint.m_erp = 1;
+ joint.m_life = 0;
+ joint.m_maxlife = 0;
+ joint.m_split = 1;
+ joint.m_drift = depth*res.normal;
+ joint.m_normal = res.normal;
+ joint.m_delete = false;
+ joint.m_friction = fv.length2()<(-rvac*friction)?1:friction;
+ joint.m_massmatrix = ImpulseMatrix( ba.invMass(),ba.invWorldInertia(),joint.m_rpos[0],
+ bb.invMass(),bb.invWorldInertia(),joint.m_rpos[1]);
+ return(true);
}
- return(false);
+ return(false);
}
};
//
@@ -709,52 +707,53 @@ struct btSoftColliders
//
struct CollideCL_RS : ClusterBase
{
- btSoftBody* psb;
- btRigidBody* prb;
- void Process(const btDbvtNode* leaf)
+ btSoftBody* psb;
+
+ btCollisionObject* m_colObj;
+ void Process(const btDbvtNode* leaf)
{
- btSoftBody::Cluster* cluster=(btSoftBody::Cluster*)leaf->data;
- btSoftClusterCollisionShape cshape(cluster);
- const btConvexShape* rshape=(const btConvexShape*)prb->getCollisionShape();
- btGjkEpaSolver2::sResults res;
- if(btGjkEpaSolver2::SignedDistance( &cshape,btTransform::getIdentity(),
- rshape,prb->getInterpolationWorldTransform(),
- btVector3(1,0,0),res))
+ btSoftBody::Cluster* cluster=(btSoftBody::Cluster*)leaf->data;
+ btSoftClusterCollisionShape cshape(cluster);
+ const btConvexShape* rshape=(const btConvexShape*)m_colObj->getCollisionShape();
+ btGjkEpaSolver2::sResults res;
+ if(btGjkEpaSolver2::SignedDistance( &cshape,btTransform::getIdentity(),
+ rshape,m_colObj->getInterpolationWorldTransform(),
+ btVector3(1,0,0),res))
{
- btSoftBody::CJoint joint;
- if(SolveContact(res,cluster,prb,joint))
+ btSoftBody::CJoint joint;
+ if(SolveContact(res,cluster,m_colObj,joint))//prb,joint))
{
- btSoftBody::CJoint* pj=new(btAlignedAlloc(sizeof(btSoftBody::CJoint),16)) btSoftBody::CJoint();
- *pj=joint;psb->m_joints.push_back(pj);
- if(prb->isStaticOrKinematicObject())
+ btSoftBody::CJoint* pj=new(btAlignedAlloc(sizeof(btSoftBody::CJoint),16)) btSoftBody::CJoint();
+ *pj=joint;psb->m_joints.push_back(pj);
+ if(m_colObj->isStaticOrKinematicObject())
{
- pj->m_erp *= psb->m_cfg.kSKHR_CL;
- pj->m_split *= psb->m_cfg.kSK_SPLT_CL;
+ pj->m_erp *= psb->m_cfg.kSKHR_CL;
+ pj->m_split *= psb->m_cfg.kSK_SPLT_CL;
}
else
{
- pj->m_erp *= psb->m_cfg.kSRHR_CL;
- pj->m_split *= psb->m_cfg.kSR_SPLT_CL;
+ pj->m_erp *= psb->m_cfg.kSRHR_CL;
+ pj->m_split *= psb->m_cfg.kSR_SPLT_CL;
}
}
}
}
- void Process(btSoftBody* ps,btRigidBody* pr)
+ void Process(btSoftBody* ps,btCollisionObject* colOb)
{
- psb = ps;
- prb = pr;
- idt = ps->m_sst.isdt;
- margin = ps->getCollisionShape()->getMargin()+
- pr->getCollisionShape()->getMargin();
- friction = btMin(psb->m_cfg.kDF,prb->getFriction());
- btVector3 mins;
- btVector3 maxs;
-
- ATTRIBUTE_ALIGNED16(btDbvtVolume) volume;
- pr->getCollisionShape()->getAabb(pr->getInterpolationWorldTransform(),mins,maxs);
- volume=btDbvtVolume::FromMM(mins,maxs);
- volume.Expand(btVector3(1,1,1)*margin);
- btDbvt::collideTV(ps->m_cdbvt.m_root,volume,*this);
+ psb = ps;
+ m_colObj = colOb;
+ idt = ps->m_sst.isdt;
+ margin = m_colObj->getCollisionShape()->getMargin();
+ ///Bullet rigid body uses multiply instead of minimum to determine combined friction. Some customization would be useful.
+ friction = btMin(psb->m_cfg.kDF,m_colObj->getFriction());
+ btVector3 mins;
+ btVector3 maxs;
+
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) volume;
+ colOb->getCollisionShape()->getAabb(colOb->getInterpolationWorldTransform(),mins,maxs);
+ volume=btDbvtVolume::FromMM(mins,maxs);
+ volume.Expand(btVector3(1,1,1)*margin);
+ ps->m_cdbvt.collideTV(ps->m_cdbvt.m_root,volume,*this);
}
};
//
@@ -762,36 +761,53 @@ struct btSoftColliders
//
struct CollideCL_SS : ClusterBase
{
- btSoftBody* bodies[2];
- void Process(const btDbvtNode* la,const btDbvtNode* lb)
+ btSoftBody* bodies[2];
+ void Process(const btDbvtNode* la,const btDbvtNode* lb)
{
- btSoftBody::Cluster* cla=(btSoftBody::Cluster*)la->data;
- btSoftBody::Cluster* clb=(btSoftBody::Cluster*)lb->data;
- btSoftClusterCollisionShape csa(cla);
- btSoftClusterCollisionShape csb(clb);
- btGjkEpaSolver2::sResults res;
- if(btGjkEpaSolver2::SignedDistance( &csa,btTransform::getIdentity(),
- &csb,btTransform::getIdentity(),
- cla->m_com-clb->m_com,res))
+ btSoftBody::Cluster* cla=(btSoftBody::Cluster*)la->data;
+ btSoftBody::Cluster* clb=(btSoftBody::Cluster*)lb->data;
+
+
+ bool connected=false;
+ if ((bodies[0]==bodies[1])&&(bodies[0]->m_clusterConnectivity.size()))
{
- btSoftBody::CJoint joint;
- if(SolveContact(res,cla,clb,joint))
+ connected = bodies[0]->m_clusterConnectivity[cla->m_clusterIndex+bodies[0]->m_clusters.size()*clb->m_clusterIndex];
+ }
+
+ if (!connected)
+ {
+ btSoftClusterCollisionShape csa(cla);
+ btSoftClusterCollisionShape csb(clb);
+ btGjkEpaSolver2::sResults res;
+ if(btGjkEpaSolver2::SignedDistance( &csa,btTransform::getIdentity(),
+ &csb,btTransform::getIdentity(),
+ cla->m_com-clb->m_com,res))
{
- btSoftBody::CJoint* pj=new(btAlignedAlloc(sizeof(btSoftBody::CJoint),16)) btSoftBody::CJoint();
- *pj=joint;bodies[0]->m_joints.push_back(pj);
- pj->m_erp *= btMax(bodies[0]->m_cfg.kSSHR_CL,bodies[1]->m_cfg.kSSHR_CL);
- pj->m_split *= (bodies[0]->m_cfg.kSS_SPLT_CL+bodies[1]->m_cfg.kSS_SPLT_CL)/2;
+ btSoftBody::CJoint joint;
+ if(SolveContact(res,cla,clb,joint))
+ {
+ btSoftBody::CJoint* pj=new(btAlignedAlloc(sizeof(btSoftBody::CJoint),16)) btSoftBody::CJoint();
+ *pj=joint;bodies[0]->m_joints.push_back(pj);
+ pj->m_erp *= btMax(bodies[0]->m_cfg.kSSHR_CL,bodies[1]->m_cfg.kSSHR_CL);
+ pj->m_split *= (bodies[0]->m_cfg.kSS_SPLT_CL+bodies[1]->m_cfg.kSS_SPLT_CL)/2;
+ }
}
+ } else
+ {
+ static int count=0;
+ count++;
+ //printf("count=%d\n",count);
+
}
}
- void Process(btSoftBody* psa,btSoftBody* psb)
+ void Process(btSoftBody* psa,btSoftBody* psb)
{
- idt = psa->m_sst.isdt;
- margin = (psa->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin())/2;
- friction = btMin(psa->m_cfg.kDF,psb->m_cfg.kDF);
- bodies[0] = psa;
- bodies[1] = psb;
- btDbvt::collideTT(psa->m_cdbvt.m_root,psb->m_cdbvt.m_root,*this);
+ idt = psa->m_sst.isdt;
+ margin = (psa->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin())/2;
+ friction = btMin(psa->m_cfg.kDF,psb->m_cfg.kDF);
+ bodies[0] = psa;
+ bodies[1] = psb;
+ psa->m_cdbvt.collideTT(psa->m_cdbvt.m_root,psb->m_cdbvt.m_root,*this);
}
};
//
@@ -799,96 +815,99 @@ struct btSoftColliders
//
struct CollideSDF_RS : btDbvt::ICollide
{
- void Process(const btDbvtNode* leaf)
+ void Process(const btDbvtNode* leaf)
{
- btSoftBody::Node* node=(btSoftBody::Node*)leaf->data;
- DoNode(*node);
+ btSoftBody::Node* node=(btSoftBody::Node*)leaf->data;
+ DoNode(*node);
}
- void DoNode(btSoftBody::Node& n) const
+ void DoNode(btSoftBody::Node& n) const
{
- const btScalar m=n.m_im>0?dynmargin:stamargin;
- btSoftBody::RContact c;
- if( (!n.m_battach)&&
- psb->checkContact(prb,n.m_x,m,c.m_cti))
+ const btScalar m=n.m_im>0?dynmargin:stamargin;
+ btSoftBody::RContact c;
+ if( (!n.m_battach)&&
+ psb->checkContact(m_colObj1,n.m_x,m,c.m_cti))
{
- const btScalar ima=n.m_im;
- const btScalar imb=prb->getInvMass();
- const btScalar ms=ima+imb;
- if(ms>0)
+ const btScalar ima=n.m_im;
+ const btScalar imb= m_rigidBody? m_rigidBody->getInvMass() : 0.f;
+ const btScalar ms=ima+imb;
+ if(ms>0)
{
- const btTransform& wtr=prb->getInterpolationWorldTransform();
- const btMatrix3x3& iwi=prb->getInvInertiaTensorWorld();
- const btVector3 ra=n.m_x-wtr.getOrigin();
- const btVector3 va=prb->getVelocityInLocalPoint(ra)*psb->m_sst.sdt;
- const btVector3 vb=n.m_x-n.m_q;
- const btVector3 vr=vb-va;
- const btScalar dn=dot(vr,c.m_cti.m_normal);
- const btVector3 fv=vr-c.m_cti.m_normal*dn;
- const btScalar fc=psb->m_cfg.kDF*prb->getFriction();
- c.m_node = &n;
- c.m_c0 = ImpulseMatrix(psb->m_sst.sdt,ima,imb,iwi,ra);
- c.m_c1 = ra;
- c.m_c2 = ima*psb->m_sst.sdt;
- c.m_c3 = fv.length2()<(btFabs(dn)*fc)?0:1-fc;
- c.m_c4 = prb->isStaticOrKinematicObject()?psb->m_cfg.kKHR:psb->m_cfg.kCHR;
- psb->m_rcontacts.push_back(c);
- prb->activate();
+ const btTransform& wtr=m_rigidBody?m_rigidBody->getInterpolationWorldTransform() : m_colObj1->getWorldTransform();
+ static const btMatrix3x3 iwiStatic(0,0,0,0,0,0,0,0,0);
+ const btMatrix3x3& iwi=m_rigidBody?m_rigidBody->getInvInertiaTensorWorld() : iwiStatic;
+ const btVector3 ra=n.m_x-wtr.getOrigin();
+ const btVector3 va=m_rigidBody ? m_rigidBody->getVelocityInLocalPoint(ra)*psb->m_sst.sdt : btVector3(0,0,0);
+ const btVector3 vb=n.m_x-n.m_q;
+ const btVector3 vr=vb-va;
+ const btScalar dn=dot(vr,c.m_cti.m_normal);
+ const btVector3 fv=vr-c.m_cti.m_normal*dn;
+ const btScalar fc=psb->m_cfg.kDF*m_colObj1->getFriction();
+ c.m_node = &n;
+ c.m_c0 = ImpulseMatrix(psb->m_sst.sdt,ima,imb,iwi,ra);
+ c.m_c1 = ra;
+ c.m_c2 = ima*psb->m_sst.sdt;
+ c.m_c3 = fv.length2()<(btFabs(dn)*fc)?0:1-fc;
+ c.m_c4 = m_colObj1->isStaticOrKinematicObject()?psb->m_cfg.kKHR:psb->m_cfg.kCHR;
+ psb->m_rcontacts.push_back(c);
+ if (m_rigidBody)
+ m_rigidBody->activate();
}
}
}
- btSoftBody* psb;
- btRigidBody* prb;
- btScalar dynmargin;
- btScalar stamargin;
+ btSoftBody* psb;
+ btCollisionObject* m_colObj1;
+ btRigidBody* m_rigidBody;
+ btScalar dynmargin;
+ btScalar stamargin;
};
//
// CollideVF_SS
//
struct CollideVF_SS : btDbvt::ICollide
{
- void Process(const btDbvtNode* lnode,
- const btDbvtNode* lface)
+ void Process(const btDbvtNode* lnode,
+ const btDbvtNode* lface)
{
- btSoftBody::Node* node=(btSoftBody::Node*)lnode->data;
- btSoftBody::Face* face=(btSoftBody::Face*)lface->data;
- btVector3 o=node->m_x;
- btVector3 p;
- btScalar d=SIMD_INFINITY;
- ProjectOrigin( face->m_n[0]->m_x-o,
- face->m_n[1]->m_x-o,
- face->m_n[2]->m_x-o,
- p,d);
- const btScalar m=mrg+(o-node->m_q).length()*2;
- if(d<(m*m))
+ btSoftBody::Node* node=(btSoftBody::Node*)lnode->data;
+ btSoftBody::Face* face=(btSoftBody::Face*)lface->data;
+ btVector3 o=node->m_x;
+ btVector3 p;
+ btScalar d=SIMD_INFINITY;
+ ProjectOrigin( face->m_n[0]->m_x-o,
+ face->m_n[1]->m_x-o,
+ face->m_n[2]->m_x-o,
+ p,d);
+ const btScalar m=mrg+(o-node->m_q).length()*2;
+ if(d<(m*m))
{
- const btSoftBody::Node* n[]={face->m_n[0],face->m_n[1],face->m_n[2]};
- const btVector3 w=BaryCoord(n[0]->m_x,n[1]->m_x,n[2]->m_x,p+o);
- const btScalar ma=node->m_im;
- btScalar mb=BaryEval(n[0]->m_im,n[1]->m_im,n[2]->m_im,w);
- if( (n[0]->m_im<=0)||
- (n[1]->m_im<=0)||
- (n[2]->m_im<=0))
+ const btSoftBody::Node* n[]={face->m_n[0],face->m_n[1],face->m_n[2]};
+ const btVector3 w=BaryCoord(n[0]->m_x,n[1]->m_x,n[2]->m_x,p+o);
+ const btScalar ma=node->m_im;
+ btScalar mb=BaryEval(n[0]->m_im,n[1]->m_im,n[2]->m_im,w);
+ if( (n[0]->m_im<=0)||
+ (n[1]->m_im<=0)||
+ (n[2]->m_im<=0))
{
- mb=0;
+ mb=0;
}
- const btScalar ms=ma+mb;
- if(ms>0)
+ const btScalar ms=ma+mb;
+ if(ms>0)
{
- btSoftBody::SContact c;
- c.m_normal = p/-btSqrt(d);
- c.m_margin = m;
- c.m_node = node;
- c.m_face = face;
- c.m_weights = w;
- c.m_friction = btMax(psb[0]->m_cfg.kDF,psb[1]->m_cfg.kDF);
- c.m_cfm[0] = ma/ms*psb[0]->m_cfg.kSHR;
- c.m_cfm[1] = mb/ms*psb[1]->m_cfg.kSHR;
- psb[0]->m_scontacts.push_back(c);
+ btSoftBody::SContact c;
+ c.m_normal = p/-btSqrt(d);
+ c.m_margin = m;
+ c.m_node = node;
+ c.m_face = face;
+ c.m_weights = w;
+ c.m_friction = btMax(psb[0]->m_cfg.kDF,psb[1]->m_cfg.kDF);
+ c.m_cfm[0] = ma/ms*psb[0]->m_cfg.kSHR;
+ c.m_cfm[1] = mb/ms*psb[1]->m_cfg.kSHR;
+ psb[0]->m_scontacts.push_back(c);
}
}
}
- btSoftBody* psb[2];
- btScalar mrg;
+ btSoftBody* psb[2];
+ btScalar mrg;
};
};
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp b/extern/bullet2/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp
index 53ac2782583..f5a67f6d895 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp
@@ -29,10 +29,10 @@ btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfigura
mem = btAlignedAlloc(sizeof(btSoftSoftCollisionAlgorithm::CreateFunc),16);
m_softSoftCreateFunc = new(mem) btSoftSoftCollisionAlgorithm::CreateFunc;
-
+
mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16);
m_softRigidConvexCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc;
-
+
mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16);
m_swappedSoftRigidConvexCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc;
m_swappedSoftRigidConvexCreateFunc->m_swapped=true;
@@ -40,26 +40,27 @@ btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfigura
#ifdef ENABLE_SOFTBODY_CONCAVE_COLLISIONS
mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc),16);
m_softRigidConcaveCreateFunc = new(mem) btSoftBodyConcaveCollisionAlgorithm::CreateFunc;
-
+
mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc),16);
m_swappedSoftRigidConcaveCreateFunc = new(mem) btSoftBodyConcaveCollisionAlgorithm::SwappedCreateFunc;
m_swappedSoftRigidConcaveCreateFunc->m_swapped=true;
#endif
//replace pool by a new one, with potential larger size
-
+
if (m_ownsCollisionAlgorithmPool && m_collisionAlgorithmPool)
{
int curElemSize = m_collisionAlgorithmPool->getElementSize();
///calculate maximum element size, big enough to fit any collision algorithm in the memory pool
-
-
+
+
int maxSize0 = sizeof(btSoftSoftCollisionAlgorithm);
int maxSize1 = sizeof(btSoftRigidCollisionAlgorithm);
int maxSize2 = sizeof(btSoftBodyConcaveCollisionAlgorithm);
int collisionAlgorithmMaxElementSize = btMax(maxSize0,maxSize1);
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2);
+
if (collisionAlgorithmMaxElementSize > curElemSize)
{
m_collisionAlgorithmPool->~btPoolAllocator();
@@ -69,9 +70,6 @@ btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfigura
}
}
-
-
-
}
btSoftBodyRigidBodyCollisionConfiguration::~btSoftBodyRigidBodyCollisionConfiguration()
@@ -93,7 +91,7 @@ btSoftBodyRigidBodyCollisionConfiguration::~btSoftBodyRigidBodyCollisionConfigur
btAlignedFree( m_swappedSoftRigidConcaveCreateFunc);
#endif
}
-
+
///creation of soft-soft and soft-rigid, and otherwise fallback to base class implementation
btCollisionAlgorithmCreateFunc* btSoftBodyRigidBodyCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1)
{
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h b/extern/bullet2/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h
index 41c3af96939..21addcfe2e1 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h
@@ -32,7 +32,7 @@ class btSoftBodyRigidBodyCollisionConfiguration : public btDefaultCollisionConfi
btCollisionAlgorithmCreateFunc* m_swappedSoftRigidConvexCreateFunc;
btCollisionAlgorithmCreateFunc* m_softRigidConcaveCreateFunc;
btCollisionAlgorithmCreateFunc* m_swappedSoftRigidConcaveCreateFunc;
-
+
public:
btSoftBodyRigidBodyCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo = btDefaultCollisionConstructionInfo());
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp b/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp
index e5feb5ef749..11ad9e7daba 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp
@@ -35,13 +35,13 @@ m_isSwapped(isSwapped)
btSoftRigidCollisionAlgorithm::~btSoftRigidCollisionAlgorithm()
{
-
+
//m_softBody->m_overlappingRigidBodies.remove(m_rigidCollisionObject);
/*if (m_ownManifold)
{
- if (m_manifoldPtr)
- m_dispatcher->releaseManifold(m_manifoldPtr);
+ if (m_manifoldPtr)
+ m_dispatcher->releaseManifold(m_manifoldPtr);
}
*/
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h b/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h
index 74327e6c635..adc3844e363 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h
@@ -28,15 +28,15 @@ class btSoftBody;
/// btSoftRigidCollisionAlgorithm provides collision detection between btSoftBody and btRigidBody
class btSoftRigidCollisionAlgorithm : public btCollisionAlgorithm
{
-// bool m_ownManifold;
-// btPersistentManifold* m_manifoldPtr;
+ // bool m_ownManifold;
+ // btPersistentManifold* m_manifoldPtr;
btSoftBody* m_softBody;
btCollisionObject* m_rigidCollisionObject;
///for rigid versus soft (instead of soft versus rigid), we use this swapped boolean
bool m_isSwapped;
-
+
public:
btSoftRigidCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped);
@@ -52,7 +52,7 @@ public:
//we don't add any manifolds
}
-
+
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp b/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
index b363a2efbc1..a0069b95145 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
@@ -28,17 +28,17 @@ subject to the following restrictions:
btSoftRigidDynamicsWorld::btSoftRigidDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration)
:btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration)
{
-m_drawFlags = fDrawFlags::Std;
-m_drawNodeTree = true;
-m_drawFaceTree = false;
-m_drawClusterTree = false;
-m_sbi.m_broadphase = pairCache;
-m_sbi.m_dispatcher = dispatcher;
-m_sbi.m_sparsesdf.Initialize();
-m_sbi.m_sparsesdf.Reset();
+ m_drawFlags = fDrawFlags::Std;
+ m_drawNodeTree = true;
+ m_drawFaceTree = false;
+ m_drawClusterTree = false;
+ m_sbi.m_broadphase = pairCache;
+ m_sbi.m_dispatcher = dispatcher;
+ m_sbi.m_sparsesdf.Initialize();
+ m_sbi.m_sparsesdf.Reset();
}
-
+
btSoftRigidDynamicsWorld::~btSoftRigidDynamicsWorld()
{
@@ -55,7 +55,7 @@ void btSoftRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
psb->predictMotion(timeStep);
}
}
-
+
void btSoftRigidDynamicsWorld::internalSingleStepSimulation( btScalar timeStep)
{
btDiscreteDynamicsWorld::internalSingleStepSimulation( timeStep );
@@ -63,6 +63,13 @@ void btSoftRigidDynamicsWorld::internalSingleStepSimulation( btScalar timeStep)
///solve soft bodies constraints
solveSoftBodiesConstraints();
+ //self collisions
+ for ( int i=0;i<m_softBodies.size();i++)
+ {
+ btSoftBody* psb=(btSoftBody*)m_softBodies[i];
+ psb->defaultCollisionHandler(psb);
+ }
+
///update soft bodies
updateSoftBodies();
@@ -71,7 +78,7 @@ void btSoftRigidDynamicsWorld::internalSingleStepSimulation( btScalar timeStep)
void btSoftRigidDynamicsWorld::updateSoftBodies()
{
BT_PROFILE("updateSoftBodies");
-
+
for ( int i=0;i<m_softBodies.size();i++)
{
btSoftBody* psb=(btSoftBody*)m_softBodies[i];
@@ -82,12 +89,12 @@ void btSoftRigidDynamicsWorld::updateSoftBodies()
void btSoftRigidDynamicsWorld::solveSoftBodiesConstraints()
{
BT_PROFILE("solveSoftConstraints");
-
+
if(m_softBodies.size())
- {
+ {
btSoftBody::solveClusters(m_softBodies);
- }
-
+ }
+
for(int i=0;i<m_softBodies.size();++i)
{
btSoftBody* psb=(btSoftBody*)m_softBodies[i];
@@ -100,8 +107,8 @@ void btSoftRigidDynamicsWorld::addSoftBody(btSoftBody* body)
m_softBodies.push_back(body);
btCollisionWorld::addCollisionObject(body,
- btBroadphaseProxy::DefaultFilter,
- btBroadphaseProxy::AllFilter);
+ btBroadphaseProxy::DefaultFilter,
+ btBroadphaseProxy::AllFilter);
}
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.h b/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.h
index aa8795d897b..edb848e2481 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.h
@@ -23,7 +23,7 @@ typedef btAlignedObjectArray<btSoftBody*> btSoftBodyArray;
class btSoftRigidDynamicsWorld : public btDiscreteDynamicsWorld
{
-
+
btSoftBodyArray m_softBodies;
int m_drawFlags;
bool m_drawNodeTree;
@@ -32,9 +32,9 @@ class btSoftRigidDynamicsWorld : public btDiscreteDynamicsWorld
btSoftBodyWorldInfo m_sbi;
protected:
-
+
virtual void predictUnconstraintMotion(btScalar timeStep);
-
+
virtual void internalSingleStepSimulation( btScalar timeStep);
void updateSoftBodies();
@@ -43,17 +43,17 @@ protected:
public:
-
+
btSoftRigidDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration);
virtual ~btSoftRigidDynamicsWorld();
-
+
virtual void debugDrawWorld();
-
+
void addSoftBody(btSoftBody* body);
void removeSoftBody(btSoftBody* body);
-
+
int getDrawFlags() const { return(m_drawFlags); }
void setDrawFlags(int f) { m_drawFlags=f; }
@@ -66,7 +66,7 @@ public:
return m_sbi;
}
-
+
btSoftBodyArray& getSoftBodyArray()
{
return m_softBodies;
@@ -76,7 +76,7 @@ public:
{
return m_softBodies;
}
-
+
};
#endif //BT_SOFT_RIGID_DYNAMICS_WORLD_H
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h b/extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h
index 7ca9c3415c9..1b34e0af60f 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h
@@ -33,7 +33,7 @@ class btSoftSoftCollisionAlgorithm : public btCollisionAlgorithm
btSoftBody* m_softBody0;
btSoftBody* m_softBody1;
-
+
public:
btSoftSoftCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
: btCollisionAlgorithm(ci) {}
diff --git a/extern/bullet2/src/BulletSoftBody/btSparseSDF.h b/extern/bullet2/src/BulletSoftBody/btSparseSDF.h
index eafe74be1ae..cc4266732ae 100644
--- a/extern/bullet2/src/BulletSoftBody/btSparseSDF.h
+++ b/extern/bullet2/src/BulletSoftBody/btSparseSDF.h
@@ -23,139 +23,139 @@ subject to the following restrictions:
// Modified Paul Hsieh hash
template <const int DWORDLEN>
unsigned int HsiehHash(const void* pdata)
- {
+{
const unsigned short* data=(const unsigned short*)pdata;
unsigned hash=DWORDLEN<<2,tmp;
for(int i=0;i<DWORDLEN;++i)
- {
+ {
hash += data[0];
tmp = (data[1]<<11)^hash;
hash = (hash<<16)^tmp;
data += 2;
hash += hash>>11;
- }
+ }
hash^=hash<<3;hash+=hash>>5;
hash^=hash<<4;hash+=hash>>17;
hash^=hash<<25;hash+=hash>>6;
return(hash);
- }
+}
template <const int CELLSIZE>
struct btSparseSdf
- {
+{
//
// Inner types
//
struct IntFrac
- {
+ {
int b;
int i;
btScalar f;
- };
+ };
struct Cell
- {
+ {
btScalar d[CELLSIZE+1][CELLSIZE+1][CELLSIZE+1];
int c[3];
int puid;
unsigned hash;
btCollisionShape* pclient;
Cell* next;
- };
+ };
//
// Fields
//
-
+
btAlignedObjectArray<Cell*> cells;
btScalar voxelsz;
int puid;
int ncells;
int nprobes;
int nqueries;
-
+
//
// Methods
//
-
+
//
void Initialize(int hashsize=2383)
- {
+ {
cells.resize(hashsize,0);
Reset();
- }
+ }
//
void Reset()
- {
+ {
for(int i=0,ni=cells.size();i<ni;++i)
- {
+ {
Cell* pc=cells[i];
cells[i]=0;
while(pc)
- {
+ {
Cell* pn=pc->next;
delete pc;
pc=pn;
- }
}
+ }
voxelsz =0.25;
puid =0;
ncells =0;
nprobes =1;
nqueries =1;
- }
+ }
//
void GarbageCollect(int lifetime=256)
- {
+ {
const int life=puid-lifetime;
for(int i=0;i<cells.size();++i)
- {
+ {
Cell*& root=cells[i];
Cell* pp=0;
Cell* pc=root;
while(pc)
- {
+ {
Cell* pn=pc->next;
if(pc->puid<life)
- {
+ {
if(pp) pp->next=pn; else root=pn;
delete pc;pc=pp;--ncells;
- }
- pp=pc;pc=pn;
}
+ pp=pc;pc=pn;
}
+ }
//printf("GC[%d]: %d cells, PpQ: %f\r\n",puid,ncells,nprobes/(btScalar)nqueries);
nqueries=1;
nprobes=1;
- ++puid; /* TODO: Reset puid's when int range limit is reached */
- /* else setup a priority list... */
- }
+ ++puid; ///@todo: Reset puid's when int range limit is reached */
+ /* else setup a priority list... */
+ }
//
int RemoveReferences(btCollisionShape* pcs)
- {
+ {
int refcount=0;
for(int i=0;i<cells.size();++i)
- {
+ {
Cell*& root=cells[i];
Cell* pp=0;
Cell* pc=root;
while(pc)
- {
+ {
Cell* pn=pc->next;
if(pc->pclient==pcs)
- {
+ {
if(pp) pp->next=pn; else root=pn;
delete pc;pc=pp;++refcount;
- }
- pp=pc;pc=pn;
}
+ pp=pc;pc=pn;
}
- return(refcount);
}
+ return(refcount);
+ }
//
btScalar Evaluate( const btVector3& x,
- btCollisionShape* shape,
- btVector3& normal,
- btScalar margin)
- {
+ btCollisionShape* shape,
+ btVector3& normal,
+ btScalar margin)
+ {
/* Lookup cell */
const btVector3 scx=x/voxelsz;
const IntFrac ix=Decompose(scx.x());
@@ -166,19 +166,19 @@ struct btSparseSdf
Cell* c=root;
++nqueries;
while(c)
- {
+ {
++nprobes;
if( (c->hash==h) &&
(c->c[0]==ix.b) &&
(c->c[1]==iy.b) &&
(c->c[2]==iz.b) &&
(c->pclient==shape))
- { break; }
- else
- { c=c->next; }
- }
+ { break; }
+ else
+ { c=c->next; }
+ }
if(!c)
- {
+ {
++nprobes;
++ncells;
c=new Cell();
@@ -187,82 +187,82 @@ struct btSparseSdf
c->hash=h;
c->c[0]=ix.b;c->c[1]=iy.b;c->c[2]=iz.b;
BuildCell(*c);
- }
+ }
c->puid=puid;
/* Extract infos */
const int o[]={ ix.i,iy.i,iz.i};
const btScalar d[]={ c->d[o[0]+0][o[1]+0][o[2]+0],
- c->d[o[0]+1][o[1]+0][o[2]+0],
- c->d[o[0]+1][o[1]+1][o[2]+0],
- c->d[o[0]+0][o[1]+1][o[2]+0],
- c->d[o[0]+0][o[1]+0][o[2]+1],
- c->d[o[0]+1][o[1]+0][o[2]+1],
- c->d[o[0]+1][o[1]+1][o[2]+1],
- c->d[o[0]+0][o[1]+1][o[2]+1]};
+ c->d[o[0]+1][o[1]+0][o[2]+0],
+ c->d[o[0]+1][o[1]+1][o[2]+0],
+ c->d[o[0]+0][o[1]+1][o[2]+0],
+ c->d[o[0]+0][o[1]+0][o[2]+1],
+ c->d[o[0]+1][o[1]+0][o[2]+1],
+ c->d[o[0]+1][o[1]+1][o[2]+1],
+ c->d[o[0]+0][o[1]+1][o[2]+1]};
/* Normal */
- #if 1
+#if 1
const btScalar gx[]={ d[1]-d[0],d[2]-d[3],
- d[5]-d[4],d[6]-d[7]};
+ d[5]-d[4],d[6]-d[7]};
const btScalar gy[]={ d[3]-d[0],d[2]-d[1],
- d[7]-d[4],d[6]-d[5]};
+ d[7]-d[4],d[6]-d[5]};
const btScalar gz[]={ d[4]-d[0],d[5]-d[1],
- d[7]-d[3],d[6]-d[2]};
+ d[7]-d[3],d[6]-d[2]};
normal.setX(Lerp( Lerp(gx[0],gx[1],iy.f),
- Lerp(gx[2],gx[3],iy.f),iz.f));
+ Lerp(gx[2],gx[3],iy.f),iz.f));
normal.setY(Lerp( Lerp(gy[0],gy[1],ix.f),
- Lerp(gy[2],gy[3],ix.f),iz.f));
+ Lerp(gy[2],gy[3],ix.f),iz.f));
normal.setZ(Lerp( Lerp(gz[0],gz[1],ix.f),
- Lerp(gz[2],gz[3],ix.f),iy.f));
+ Lerp(gz[2],gz[3],ix.f),iy.f));
normal = normal.normalized();
- #else
+#else
normal = btVector3(d[1]-d[0],d[3]-d[0],d[4]-d[0]).normalized();
- #endif
+#endif
/* Distance */
const btScalar d0=Lerp(Lerp(d[0],d[1],ix.f),
- Lerp(d[3],d[2],ix.f),iy.f);
+ Lerp(d[3],d[2],ix.f),iy.f);
const btScalar d1=Lerp(Lerp(d[4],d[5],ix.f),
- Lerp(d[7],d[6],ix.f),iy.f);
+ Lerp(d[7],d[6],ix.f),iy.f);
return(Lerp(d0,d1,iz.f)-margin);
- }
+ }
//
void BuildCell(Cell& c)
- {
+ {
const btVector3 org=btVector3( (btScalar)c.c[0],
- (btScalar)c.c[1],
- (btScalar)c.c[2]) *
- CELLSIZE*voxelsz;
+ (btScalar)c.c[1],
+ (btScalar)c.c[2]) *
+ CELLSIZE*voxelsz;
for(int k=0;k<=CELLSIZE;++k)
- {
+ {
const btScalar z=voxelsz*k+org.z();
for(int j=0;j<=CELLSIZE;++j)
- {
+ {
const btScalar y=voxelsz*j+org.y();
for(int i=0;i<=CELLSIZE;++i)
- {
+ {
const btScalar x=voxelsz*i+org.x();
c.d[i][j][k]=DistanceToShape( btVector3(x,y,z),
- c.pclient);
- }
+ c.pclient);
}
}
}
+ }
//
static inline btScalar DistanceToShape(const btVector3& x,
- btCollisionShape* shape)
- {
+ btCollisionShape* shape)
+ {
btTransform unit;
unit.setIdentity();
if(shape->isConvex())
- {
+ {
btGjkEpaSolver2::sResults res;
btConvexShape* csh=static_cast<btConvexShape*>(shape);
return(btGjkEpaSolver2::SignedDistance(x,0,csh,unit,res));
- }
- return(0);
}
+ return(0);
+ }
//
static inline IntFrac Decompose(btScalar x)
- {
+ {
/* That one need a lot of improvements... */
/* Remove test, faster floor... */
IntFrac r;
@@ -272,18 +272,18 @@ struct btSparseSdf
const btScalar k=(x-r.b)*CELLSIZE;
r.i=(int)k;r.f=k-r.i;r.b-=o;
return(r);
- }
+ }
//
static inline btScalar Lerp(btScalar a,btScalar b,btScalar t)
- {
+ {
return(a+(b-a)*t);
- }
+ }
+
-
//
static inline unsigned int Hash(int x,int y,int z,btCollisionShape* shape)
- {
+ {
struct btS
{
int x,y,z;
@@ -291,16 +291,16 @@ struct btSparseSdf
};
btS myset;
-
+
myset.x=x;myset.y=y;myset.z=z;myset.p=shape;
const void* ptr = &myset;
unsigned int result = HsiehHash<sizeof(btS)/4> (ptr);
-
+
return result;
- }
+ }
};
-
+
#endif
diff --git a/extern/bullet2/src/LinearMath/CMakeLists.txt b/extern/bullet2/src/LinearMath/CMakeLists.txt
index 02ffaad7228..99d5a6a2fef 100644
--- a/extern/bullet2/src/LinearMath/CMakeLists.txt
+++ b/extern/bullet2/src/LinearMath/CMakeLists.txt
@@ -3,7 +3,14 @@ INCLUDE_DIRECTORIES(
${BULLET_PHYSICS_SOURCE_DIR}/src }
)
-ADD_LIBRARY(LibLinearMath
+SET(LinearMath_SRCS
+ btConvexHull.cpp
+ btQuickprof.cpp
+ btGeometryUtil.cpp
+ btAlignedAllocator.cpp
+)
+
+SET(LinearMath_HDRS
btAlignedObjectArray.h
btList.h
btPoolAllocator.h
@@ -16,7 +23,6 @@ ADD_LIBRARY(LibLinearMath
btScalar.h
btAabbUtil2.h
btConvexHull.h
- btConvexHull.cpp
btMinMax.h
btQuaternion.h
btStackAlloc.h
@@ -25,11 +31,21 @@ ADD_LIBRARY(LibLinearMath
btTransform.h
btAlignedAllocator.h
btIDebugDraw.h
- btPoint3.h
btQuickprof.h
btTransformUtil.h
- btQuickprof.cpp
- btGeometryUtil.cpp
- btAlignedAllocator.cpp
)
+ADD_LIBRARY(LinearMath ${LinearMath_SRCS} ${LinearMath_HDRS})
+SET_TARGET_PROPERTIES(LinearMath PROPERTIES VERSION ${BULLET_VERSION})
+SET_TARGET_PROPERTIES(LinearMath PROPERTIES SOVERSION ${BULLET_VERSION})
+
+#FILES_MATCHING requires CMake 2.6
+IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
+ INSTALL(TARGETS LinearMath DESTINATION lib)
+ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include FILES_MATCHING PATTERN "*.h")
+ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
+
+IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
+ SET_TARGET_PROPERTIES(LinearMath PROPERTIES FRAMEWORK true)
+ SET_TARGET_PROPERTIES(LinearMath PROPERTIES PUBLIC_HEADER "${LinearMath_HDRS}")
+ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
diff --git a/extern/bullet2/src/LinearMath/btAabbUtil2.h b/extern/bullet2/src/LinearMath/btAabbUtil2.h
index 275c4914628..532ce1bf633 100644
--- a/extern/bullet2/src/LinearMath/btAabbUtil2.h
+++ b/extern/bullet2/src/LinearMath/btAabbUtil2.h
@@ -21,6 +21,8 @@ subject to the following restrictions:
#include "btVector3.h"
#include "btMinMax.h"
+
+
SIMD_FORCE_INLINE void AabbExpand (btVector3& aabbMin,
btVector3& aabbMax,
const btVector3& expansionMin,
@@ -30,15 +32,26 @@ SIMD_FORCE_INLINE void AabbExpand (btVector3& aabbMin,
aabbMax = aabbMax + expansionMax;
}
+/// conservative test for overlap between two aabbs
+SIMD_FORCE_INLINE bool TestPointAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1,
+ const btVector3 &point)
+{
+ bool overlap = true;
+ overlap = (aabbMin1.getX() > point.getX() || aabbMax1.getX() < point.getX()) ? false : overlap;
+ overlap = (aabbMin1.getZ() > point.getZ() || aabbMax1.getZ() < point.getZ()) ? false : overlap;
+ overlap = (aabbMin1.getY() > point.getY() || aabbMax1.getY() < point.getY()) ? false : overlap;
+ return overlap;
+}
+
/// conservative test for overlap between two aabbs
SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1,
const btVector3 &aabbMin2, const btVector3 &aabbMax2)
{
bool overlap = true;
- overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
- overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
- overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
+ overlap = (aabbMin1.getX() > aabbMax2.getX() || aabbMax1.getX() < aabbMin2.getX()) ? false : overlap;
+ overlap = (aabbMin1.getZ() > aabbMax2.getZ() || aabbMax1.getZ() < aabbMin2.getZ()) ? false : overlap;
+ overlap = (aabbMin1.getY() > aabbMax2.getY() || aabbMax1.getY() < aabbMin2.getY()) ? false : overlap;
return overlap;
}
@@ -73,6 +86,7 @@ SIMD_FORCE_INLINE int btOutcode(const btVector3& p,const btVector3& halfExtent)
}
+
SIMD_FORCE_INLINE bool btRayAabb2(const btVector3& rayFrom,
const btVector3& rayInvDirection,
const unsigned int raySign[3],
@@ -82,10 +96,10 @@ SIMD_FORCE_INLINE bool btRayAabb2(const btVector3& rayFrom,
btScalar lambda_max)
{
btScalar tmax, tymin, tymax, tzmin, tzmax;
- tmin = (bounds[raySign[0]][0] - rayFrom[0]) * rayInvDirection[0];
- tmax = (bounds[1-raySign[0]][0] - rayFrom[0]) * rayInvDirection[0];
- tymin = (bounds[raySign[1]][1] - rayFrom[1]) * rayInvDirection[1];
- tymax = (bounds[1-raySign[1]][1] - rayFrom[1]) * rayInvDirection[1];
+ tmin = (bounds[raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX();
+ tmax = (bounds[1-raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX();
+ tymin = (bounds[raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY();
+ tymax = (bounds[1-raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY();
if ( (tmin > tymax) || (tymin > tmax) )
return false;
@@ -96,8 +110,8 @@ SIMD_FORCE_INLINE bool btRayAabb2(const btVector3& rayFrom,
if (tymax < tmax)
tmax = tymax;
- tzmin = (bounds[raySign[2]][2] - rayFrom[2]) * rayInvDirection[2];
- tzmax = (bounds[1-raySign[2]][2] - rayFrom[2]) * rayInvDirection[2];
+ tzmin = (bounds[raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ();
+ tzmax = (bounds[1-raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ();
if ( (tmin > tzmax) || (tzmin > tmax) )
return false;
@@ -196,6 +210,26 @@ SIMD_FORCE_INLINE void btTransformAabb(const btVector3& localAabbMin,const btVec
aabbMaxOut = center+extent;
}
+#define USE_BANCHLESS 1
+#ifdef USE_BANCHLESS
+ //This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360)
+ SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2)
+ {
+ return static_cast<unsigned int>(btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0])
+ & (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2])
+ & (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])),
+ 1, 0));
+ }
+#else
+ SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2)
+ {
+ bool overlap = true;
+ overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
+ overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
+ overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
+ return overlap;
+ }
+#endif //USE_BANCHLESS
#endif
diff --git a/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp b/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp
index e120289e061..a3d790f8abc 100644
--- a/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp
+++ b/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp
@@ -19,6 +19,21 @@ int gNumAlignedAllocs = 0;
int gNumAlignedFree = 0;
int gTotalBytesAlignedAllocs = 0;//detect memory leaks
+static void *btAllocDefault(size_t size)
+{
+ return malloc(size);
+}
+
+static void btFreeDefault(void *ptr)
+{
+ free(ptr);
+}
+
+static btAllocFunc *sAllocFunc = btAllocDefault;
+static btFreeFunc *sFreeFunc = btFreeDefault;
+
+
+
#if defined (BT_HAS_ALIGNED_ALLOCATOR)
#include <malloc.h>
static void *btAlignedAllocDefault(size_t size, int alignment)
@@ -49,7 +64,7 @@ static inline void *btAlignedAllocDefault(size_t size, int alignment)
char *real;
unsigned long offset;
- real = (char *)malloc(size + sizeof(void *) + (alignment-1));
+ real = (char *)sAllocFunc(size + sizeof(void *) + (alignment-1));
if (real) {
offset = (alignment - (unsigned long)(real + sizeof(void *))) & (alignment-1);
ret = (void *)((real + sizeof(void *)) + offset);
@@ -66,25 +81,14 @@ static inline void btAlignedFreeDefault(void *ptr)
if (ptr) {
real = *((void **)(ptr)-1);
- free(real);
+ sFreeFunc(real);
}
}
#endif
-static void *btAllocDefault(size_t size)
-{
- return malloc(size);
-}
-
-static void btFreeDefault(void *ptr)
-{
- free(ptr);
-}
static btAlignedAllocFunc *sAlignedAllocFunc = btAlignedAllocDefault;
static btAlignedFreeFunc *sAlignedFreeFunc = btAlignedFreeDefault;
-static btAllocFunc *sAllocFunc = btAllocDefault;
-static btFreeFunc *sFreeFunc = btFreeDefault;
void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc)
{
diff --git a/extern/bullet2/src/LinearMath/btAlignedAllocator.h b/extern/bullet2/src/LinearMath/btAlignedAllocator.h
index a252f324d77..f168f3c66c7 100644
--- a/extern/bullet2/src/LinearMath/btAlignedAllocator.h
+++ b/extern/bullet2/src/LinearMath/btAlignedAllocator.h
@@ -38,7 +38,7 @@ void btAlignedFreeInternal (void* ptr,int line,char* filename);
void* btAlignedAllocInternal (size_t size, int alignment);
void btAlignedFreeInternal (void* ptr);
- #define btAlignedAlloc(a,b) btAlignedAllocInternal(a,b)
+ #define btAlignedAlloc(size,alignment) btAlignedAllocInternal(size,alignment)
#define btAlignedFree(ptr) btAlignedFreeInternal(ptr)
#endif
@@ -49,8 +49,11 @@ typedef void (btAlignedFreeFunc)(void *memblock);
typedef void *(btAllocFunc)(size_t size);
typedef void (btFreeFunc)(void *memblock);
-void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc);
+///The developer can let all Bullet memory allocations go through a custom memory allocator, using btAlignedAllocSetCustom
void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc);
+///If the developer has already an custom aligned allocator, then btAlignedAllocSetCustomAligned can be used. The default aligned allocator pre-allocates extra memory using the non-aligned allocator, and instruments it.
+void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc);
+
///The btAlignedAllocator is a portable class for aligned memory allocations.
///Default implementations for unaligned and aligned allocations can be overridden by a custom allocator using btAlignedAllocSetCustom and btAlignedAllocSetCustomAligned.
diff --git a/extern/bullet2/src/LinearMath/btAlignedObjectArray.h b/extern/bullet2/src/LinearMath/btAlignedObjectArray.h
index 5598f0d7236..bad1eee1f63 100644
--- a/extern/bullet2/src/LinearMath/btAlignedObjectArray.h
+++ b/extern/bullet2/src/LinearMath/btAlignedObjectArray.h
@@ -58,7 +58,7 @@ class btAlignedObjectArray
{
return (size ? size*2 : 1);
}
- SIMD_FORCE_INLINE void copy(int start,int end, T* dest)
+ SIMD_FORCE_INLINE void copy(int start,int end, T* dest) const
{
int i;
for (i=start;i<end;++i)
@@ -120,13 +120,21 @@ class btAlignedObjectArray
clear();
}
- SIMD_FORCE_INLINE int capacity() const
- { // return current length of allocated storage
- return m_capacity;
+ ///Generally it is best to avoid using the copy constructor of an btAlignedObjectArray, and use a (const) reference to the array instead.
+ btAlignedObjectArray(const btAlignedObjectArray& otherArray)
+ {
+ init();
+
+ int otherSize = otherArray.size();
+ resize (otherSize);
+ otherArray.copy(0, otherSize, m_data);
}
+
+
+ /// return the number of elements in the array
SIMD_FORCE_INLINE int size() const
- { // return length of sequence
+ {
return m_size;
}
@@ -141,6 +149,7 @@ class btAlignedObjectArray
}
+ ///clear the array, deallocated memory. Generally it is better to use array.resize(0), to reduce performance overhead of run-time memory (de)allocations.
SIMD_FORCE_INLINE void clear()
{
destroy(0,size());
@@ -156,6 +165,8 @@ class btAlignedObjectArray
m_data[m_size].~T();
}
+ ///resize changes the number of elements in the array. If the new size is larger, the new elements will be constructed using the optional second argument.
+ ///when the new number of elements is smaller, the destructor will be called, but memory will not be freed, to reduce performance overhead of run-time memory (de)allocations.
SIMD_FORCE_INLINE void resize(int newsize, const T& fillData=T())
{
int curSize = size();
@@ -219,6 +230,11 @@ class btAlignedObjectArray
}
+ /// return the pre-allocated (reserved) elements, this is at least as large as the total number of elements,see size() and reserve()
+ SIMD_FORCE_INLINE int capacity() const
+ {
+ return m_capacity;
+ }
SIMD_FORCE_INLINE void reserve(int _Count)
{ // determine new minimum length of allocated storage
diff --git a/extern/bullet2/src/LinearMath/btConvexHull.cpp b/extern/bullet2/src/LinearMath/btConvexHull.cpp
index b8929a86808..419c752a1d9 100644
--- a/extern/bullet2/src/LinearMath/btConvexHull.cpp
+++ b/extern/bullet2/src/LinearMath/btConvexHull.cpp
@@ -262,8 +262,8 @@ int maxdirsterid(const T *p,int count,const T &dir,btAlignedObjectArray<int> &al
int ma=-1;
for(btScalar x = btScalar(0.0) ; x<= btScalar(360.0) ; x+= btScalar(45.0))
{
- btScalar s = sinf(SIMD_RADS_PER_DEG*(x));
- btScalar c = cosf(SIMD_RADS_PER_DEG*(x));
+ btScalar s = btSin(SIMD_RADS_PER_DEG*(x));
+ btScalar c = btCos(SIMD_RADS_PER_DEG*(x));
int mb = maxdirfiltered(p,count,dir+(u*s+v*c)*btScalar(0.025),allow);
if(ma==m && mb==m)
{
@@ -275,8 +275,8 @@ int maxdirsterid(const T *p,int count,const T &dir,btAlignedObjectArray<int> &al
int mc = ma;
for(btScalar xx = x-btScalar(40.0) ; xx <= x ; xx+= btScalar(5.0))
{
- btScalar s = sinf(SIMD_RADS_PER_DEG*(xx));
- btScalar c = cosf(SIMD_RADS_PER_DEG*(xx));
+ btScalar s = btSin(SIMD_RADS_PER_DEG*(xx));
+ btScalar c = btCos(SIMD_RADS_PER_DEG*(xx));
int md = maxdirfiltered(p,count,dir+(u*s+v*c)*btScalar(0.025),allow);
if(mc==m && md==m)
{
@@ -342,30 +342,30 @@ int shareedge(const int3 &a,const int3 &b)
return 0;
}
-class Tri;
+class btHullTriangle;
-class Tri : public int3
+class btHullTriangle : public int3
{
public:
int3 n;
int id;
int vmax;
btScalar rise;
- Tri(int a,int b,int c):int3(a,b,c),n(-1,-1,-1)
+ btHullTriangle(int a,int b,int c):int3(a,b,c),n(-1,-1,-1)
{
vmax=-1;
rise = btScalar(0.0);
}
- ~Tri()
+ ~btHullTriangle()
{
}
int &neib(int a,int b);
};
-int &Tri::neib(int a,int b)
+int &btHullTriangle::neib(int a,int b)
{
static int er=-1;
int i;
@@ -379,7 +379,7 @@ int &Tri::neib(int a,int b)
btAssert(0);
return er;
}
-void HullLibrary::b2bfix(Tri* s,Tri*t)
+void HullLibrary::b2bfix(btHullTriangle* s,btHullTriangle*t)
{
int i;
for(i=0;i<3;i++)
@@ -395,7 +395,7 @@ void HullLibrary::b2bfix(Tri* s,Tri*t)
}
}
-void HullLibrary::removeb2b(Tri* s,Tri*t)
+void HullLibrary::removeb2b(btHullTriangle* s,btHullTriangle*t)
{
b2bfix(s,t);
deAllocateTriangle(s);
@@ -403,7 +403,7 @@ void HullLibrary::removeb2b(Tri* s,Tri*t)
deAllocateTriangle(t);
}
-void HullLibrary::checkit(Tri *t)
+void HullLibrary::checkit(btHullTriangle *t)
{
(void)t;
@@ -427,36 +427,36 @@ void HullLibrary::checkit(Tri *t)
}
}
-Tri* HullLibrary::allocateTriangle(int a,int b,int c)
+btHullTriangle* HullLibrary::allocateTriangle(int a,int b,int c)
{
- void* mem = btAlignedAlloc(sizeof(Tri),16);
- Tri* tr = new (mem)Tri(a,b,c);
+ void* mem = btAlignedAlloc(sizeof(btHullTriangle),16);
+ btHullTriangle* tr = new (mem)btHullTriangle(a,b,c);
tr->id = m_tris.size();
m_tris.push_back(tr);
return tr;
}
-void HullLibrary::deAllocateTriangle(Tri* tri)
+void HullLibrary::deAllocateTriangle(btHullTriangle* tri)
{
btAssert(m_tris[tri->id]==tri);
m_tris[tri->id]=NULL;
- tri->~Tri();
+ tri->~btHullTriangle();
btAlignedFree(tri);
}
-void HullLibrary::extrude(Tri *t0,int v)
+void HullLibrary::extrude(btHullTriangle *t0,int v)
{
int3 t= *t0;
int n = m_tris.size();
- Tri* ta = allocateTriangle(v,t[1],t[2]);
+ btHullTriangle* ta = allocateTriangle(v,t[1],t[2]);
ta->n = int3(t0->n[0],n+1,n+2);
m_tris[t0->n[0]]->neib(t[1],t[2]) = n+0;
- Tri* tb = allocateTriangle(v,t[2],t[0]);
+ btHullTriangle* tb = allocateTriangle(v,t[2],t[0]);
tb->n = int3(t0->n[1],n+2,n+0);
m_tris[t0->n[1]]->neib(t[2],t[0]) = n+1;
- Tri* tc = allocateTriangle(v,t[0],t[1]);
+ btHullTriangle* tc = allocateTriangle(v,t[0],t[1]);
tc->n = int3(t0->n[2],n+0,n+1);
m_tris[t0->n[2]]->neib(t[0],t[1]) = n+2;
checkit(ta);
@@ -469,10 +469,10 @@ void HullLibrary::extrude(Tri *t0,int v)
}
-Tri* HullLibrary::extrudable(btScalar epsilon)
+btHullTriangle* HullLibrary::extrudable(btScalar epsilon)
{
int i;
- Tri *t=NULL;
+ btHullTriangle *t=NULL;
for(i=0;i<m_tris.size();i++)
{
if(!t || (m_tris[i] && t->rise<m_tris[i]->rise))
@@ -550,23 +550,23 @@ int HullLibrary::calchullgen(btVector3 *verts,int verts_count, int vlimit)
btVector3 center = (verts[p[0]]+verts[p[1]]+verts[p[2]]+verts[p[3]]) / btScalar(4.0); // a valid interior point
- Tri *t0 = allocateTriangle(p[2],p[3],p[1]); t0->n=int3(2,3,1);
- Tri *t1 = allocateTriangle(p[3],p[2],p[0]); t1->n=int3(3,2,0);
- Tri *t2 = allocateTriangle(p[0],p[1],p[3]); t2->n=int3(0,1,3);
- Tri *t3 = allocateTriangle(p[1],p[0],p[2]); t3->n=int3(1,0,2);
+ btHullTriangle *t0 = allocateTriangle(p[2],p[3],p[1]); t0->n=int3(2,3,1);
+ btHullTriangle *t1 = allocateTriangle(p[3],p[2],p[0]); t1->n=int3(3,2,0);
+ btHullTriangle *t2 = allocateTriangle(p[0],p[1],p[3]); t2->n=int3(0,1,3);
+ btHullTriangle *t3 = allocateTriangle(p[1],p[0],p[2]); t3->n=int3(1,0,2);
isextreme[p[0]]=isextreme[p[1]]=isextreme[p[2]]=isextreme[p[3]]=1;
checkit(t0);checkit(t1);checkit(t2);checkit(t3);
for(j=0;j<m_tris.size();j++)
{
- Tri *t=m_tris[j];
+ btHullTriangle *t=m_tris[j];
btAssert(t);
btAssert(t->vmax<0);
btVector3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]);
t->vmax = maxdirsterid(verts,verts_count,n,allow);
t->rise = dot(n,verts[t->vmax]-verts[(*t)[0]]);
}
- Tri *te;
+ btHullTriangle *te;
vlimit-=4;
while(vlimit >0 && ((te=extrudable(epsilon)) != 0))
{
@@ -594,7 +594,7 @@ int HullLibrary::calchullgen(btVector3 *verts,int verts_count, int vlimit)
int3 nt=*m_tris[j];
if(above(verts,nt,center,btScalar(0.01)*epsilon) || cross(verts[nt[1]]-verts[nt[0]],verts[nt[2]]-verts[nt[1]]).length()< epsilon*epsilon*btScalar(0.1) )
{
- Tri *nb = m_tris[m_tris[j]->n[0]];
+ btHullTriangle *nb = m_tris[m_tris[j]->n[0]];
btAssert(nb);btAssert(!hasvert(*nb,v));btAssert(nb->id<j);
extrude(nb,v);
j=m_tris.size();
@@ -603,7 +603,7 @@ int HullLibrary::calchullgen(btVector3 *verts,int verts_count, int vlimit)
j=m_tris.size();
while(j--)
{
- Tri *t=m_tris[j];
+ btHullTriangle *t=m_tris[j];
if(!t) continue;
if(t->vmax>=0) break;
btVector3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]);
diff --git a/extern/bullet2/src/LinearMath/btConvexHull.h b/extern/bullet2/src/LinearMath/btConvexHull.h
index 8c36307dfd6..92560bddb9c 100644
--- a/extern/bullet2/src/LinearMath/btConvexHull.h
+++ b/extern/bullet2/src/LinearMath/btConvexHull.h
@@ -137,13 +137,9 @@ class ConvexH
};
ConvexH()
{
- int i;
- i=0;
}
~ConvexH()
{
- int i;
- i=0;
}
btAlignedObjectArray<btVector3> vertices;
btAlignedObjectArray<HalfEdge> edges;
@@ -188,7 +184,7 @@ public:
class HullLibrary
{
- btAlignedObjectArray<class Tri*> m_tris;
+ btAlignedObjectArray<class btHullTriangle*> m_tris;
public:
@@ -203,15 +199,15 @@ private:
bool ComputeHull(unsigned int vcount,const btVector3 *vertices,PHullResult &result,unsigned int vlimit);
- class Tri* allocateTriangle(int a,int b,int c);
- void deAllocateTriangle(Tri*);
- void b2bfix(Tri* s,Tri*t);
+ class btHullTriangle* allocateTriangle(int a,int b,int c);
+ void deAllocateTriangle(btHullTriangle*);
+ void b2bfix(btHullTriangle* s,btHullTriangle*t);
- void removeb2b(Tri* s,Tri*t);
+ void removeb2b(btHullTriangle* s,btHullTriangle*t);
- void checkit(Tri *t);
+ void checkit(btHullTriangle *t);
- Tri* extrudable(btScalar epsilon);
+ btHullTriangle* extrudable(btScalar epsilon);
int calchull(btVector3 *verts,int verts_count, TUIntArray& tris_out, int &tris_count,int vlimit);
@@ -221,7 +217,7 @@ private:
class ConvexH* ConvexHCrop(ConvexH& convex,const btPlane& slice);
- void extrude(class Tri* t0,int v);
+ void extrude(class btHullTriangle* t0,int v);
ConvexH* test_cube();
diff --git a/extern/bullet2/src/LinearMath/btIDebugDraw.h b/extern/bullet2/src/LinearMath/btIDebugDraw.h
index 563615a9a32..e5a0061b779 100644
--- a/extern/bullet2/src/LinearMath/btIDebugDraw.h
+++ b/extern/bullet2/src/LinearMath/btIDebugDraw.h
@@ -29,6 +29,7 @@ DEALINGS IN THE SOFTWARE.
#define IDEBUG_DRAW__H
#include "btVector3.h"
+#include "btTransform.h"
///The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations.
@@ -52,11 +53,26 @@ class btIDebugDraw
DBG_EnableSatComparison = 256,
DBG_DisableBulletLCP = 512,
DBG_EnableCCD = 1024,
+ DBG_DrawConstraints = (1 << 11),
+ DBG_DrawConstraintLimits = (1 << 12),
DBG_MAX_DEBUG_DRAW_MODE
};
virtual ~btIDebugDraw() {};
+ virtual void drawLine(const btVector3& from,const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
+ {
+ drawLine (from, to, fromColor);
+ }
+
+ virtual void drawBox (const btVector3& boxMin, const btVector3& boxMax, const btVector3& color, btScalar alpha)
+ {
+ }
+
+ virtual void drawSphere (const btVector3& p, btScalar radius, const btVector3& color)
+ {
+ }
+
virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0;
virtual void drawTriangle(const btVector3& v0,const btVector3& v1,const btVector3& v2,const btVector3& /*n0*/,const btVector3& /*n1*/,const btVector3& /*n2*/,const btVector3& color, btScalar alpha)
@@ -109,6 +125,171 @@ class btIDebugDraw
edgecoord[i]*=-1.f;
}
}
+ void drawTransform(const btTransform& transform, btScalar orthoLen)
+ {
+ btVector3 start = transform.getOrigin();
+ drawLine(start, start+transform.getBasis() * btVector3(orthoLen, 0, 0), btVector3(0.7f,0,0));
+ drawLine(start, start+transform.getBasis() * btVector3(0, orthoLen, 0), btVector3(0,0.7f,0));
+ drawLine(start, start+transform.getBasis() * btVector3(0, 0, orthoLen), btVector3(0,0,0.7f));
+ }
+
+ void drawArc(const btVector3& center, const btVector3& normal, const btVector3& axis, btScalar radiusA, btScalar radiusB, btScalar minAngle, btScalar maxAngle,
+ const btVector3& color, bool drawSect, btScalar stepDegrees = btScalar(10.f))
+ {
+ const btVector3& vx = axis;
+ btVector3 vy = normal.cross(axis);
+ btScalar step = stepDegrees * SIMD_RADS_PER_DEG;
+ int nSteps = (int)((maxAngle - minAngle) / step);
+ if(!nSteps) nSteps = 1;
+ btVector3 prev = center + radiusA * vx * btCos(minAngle) + radiusB * vy * btSin(minAngle);
+ if(drawSect)
+ {
+ drawLine(center, prev, color);
+ }
+ for(int i = 1; i <= nSteps; i++)
+ {
+ btScalar angle = minAngle + (maxAngle - minAngle) * btScalar(i) / btScalar(nSteps);
+ btVector3 next = center + radiusA * vx * btCos(angle) + radiusB * vy * btSin(angle);
+ drawLine(prev, next, color);
+ prev = next;
+ }
+ if(drawSect)
+ {
+ drawLine(center, prev, color);
+ }
+ }
+ void drawSpherePatch(const btVector3& center, const btVector3& up, const btVector3& axis, btScalar radius,
+ btScalar minTh, btScalar maxTh, btScalar minPs, btScalar maxPs, const btVector3& color, btScalar stepDegrees = btScalar(10.f))
+ {
+ btVector3 vA[74];
+ btVector3 vB[74];
+ btVector3 *pvA = vA, *pvB = vB, *pT;
+ btVector3 npole = center + up * radius;
+ btVector3 spole = center - up * radius;
+ btVector3 arcStart;
+ btScalar step = stepDegrees * SIMD_RADS_PER_DEG;
+ const btVector3& kv = up;
+ const btVector3& iv = axis;
+ btVector3 jv = kv.cross(iv);
+ bool drawN = false;
+ bool drawS = false;
+ if(minTh <= -SIMD_HALF_PI)
+ {
+ minTh = -SIMD_HALF_PI + step;
+ drawN = true;
+ }
+ if(maxTh >= SIMD_HALF_PI)
+ {
+ maxTh = SIMD_HALF_PI - step;
+ drawS = true;
+ }
+ if(minTh > maxTh)
+ {
+ minTh = -SIMD_HALF_PI + step;
+ maxTh = SIMD_HALF_PI - step;
+ drawN = drawS = true;
+ }
+ int n_hor = (int)((maxTh - minTh) / step) + 1;
+ if(n_hor < 2) n_hor = 2;
+ btScalar step_h = (maxTh - minTh) / btScalar(n_hor - 1);
+ bool isClosed = false;
+ if(minPs > maxPs)
+ {
+ minPs = -SIMD_PI + step;
+ maxPs = SIMD_PI;
+ isClosed = true;
+ }
+ else if((maxPs - minPs) >= SIMD_PI * btScalar(2.f))
+ {
+ isClosed = true;
+ }
+ else
+ {
+ isClosed = false;
+ }
+ int n_vert = (int)((maxPs - minPs) / step) + 1;
+ if(n_vert < 2) n_vert = 2;
+ btScalar step_v = (maxPs - minPs) / btScalar(n_vert - 1);
+ for(int i = 0; i < n_hor; i++)
+ {
+ btScalar th = minTh + btScalar(i) * step_h;
+ btScalar sth = radius * btSin(th);
+ btScalar cth = radius * btCos(th);
+ for(int j = 0; j < n_vert; j++)
+ {
+ btScalar psi = minPs + btScalar(j) * step_v;
+ btScalar sps = btSin(psi);
+ btScalar cps = btCos(psi);
+ pvB[j] = center + cth * cps * iv + cth * sps * jv + sth * kv;
+ if(i)
+ {
+ drawLine(pvA[j], pvB[j], color);
+ }
+ else if(drawS)
+ {
+ drawLine(spole, pvB[j], color);
+ }
+ if(j)
+ {
+ drawLine(pvB[j-1], pvB[j], color);
+ }
+ else
+ {
+ arcStart = pvB[j];
+ }
+ if((i == (n_hor - 1)) && drawN)
+ {
+ drawLine(npole, pvB[j], color);
+ }
+ if(isClosed)
+ {
+ if(j == (n_vert-1))
+ {
+ drawLine(arcStart, pvB[j], color);
+ }
+ }
+ else
+ {
+ if(((!i) || (i == (n_hor-1))) && ((!j) || (j == (n_vert-1))))
+ {
+ drawLine(center, pvB[j], color);
+ }
+ }
+ }
+ pT = pvA; pvA = pvB; pvB = pT;
+ }
+ }
+
+ void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btVector3& color)
+ {
+ drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMin[2]), color);
+ drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMin[2]), color);
+ drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMin[2]), color);
+ drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMin[2]), color);
+ drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
+ drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
+ drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
+ drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
+ drawLine(btVector3(bbMin[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
+ drawLine(btVector3(bbMax[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
+ drawLine(btVector3(bbMax[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
+ drawLine(btVector3(bbMin[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
+ }
+ void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btTransform& trans, const btVector3& color)
+ {
+ drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), color);
+ drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), color);
+ drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), color);
+ drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), color);
+ drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
+ drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
+ drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
+ drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
+ drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
+ drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
+ drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
+ drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
+ }
};
diff --git a/extern/bullet2/src/LinearMath/btMatrix3x3.h b/extern/bullet2/src/LinearMath/btMatrix3x3.h
index 14aa4ae2348..e45afc3c055 100644
--- a/extern/bullet2/src/LinearMath/btMatrix3x3.h
+++ b/extern/bullet2/src/LinearMath/btMatrix3x3.h
@@ -23,14 +23,16 @@ subject to the following restrictions:
-///The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with btQuaternion, btTransform and btVector3.
-///Make sure to only include a pure orthogonal matrix without scaling.
+/**@brief The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with btQuaternion, btTransform and btVector3.
+ * Make sure to only include a pure orthogonal matrix without scaling. */
class btMatrix3x3 {
public:
+ /** @brief No initializaion constructor */
btMatrix3x3 () {}
// explicit btMatrix3x3(const btScalar *m) { setFromOpenGLSubMatrix(m); }
+ /**@brief Constructor from Quaternion */
explicit btMatrix3x3(const btQuaternion& q) { setRotation(q); }
/*
template <typename btScalar>
@@ -39,6 +41,7 @@ class btMatrix3x3 {
setEulerYPR(yaw, pitch, roll);
}
*/
+ /** @brief Constructor with row major formatting */
btMatrix3x3(const btScalar& xx, const btScalar& xy, const btScalar& xz,
const btScalar& yx, const btScalar& yy, const btScalar& yz,
const btScalar& zx, const btScalar& zy, const btScalar& zz)
@@ -47,14 +50,14 @@ class btMatrix3x3 {
yx, yy, yz,
zx, zy, zz);
}
-
+ /** @brief Copy constructor */
SIMD_FORCE_INLINE btMatrix3x3 (const btMatrix3x3& other)
{
m_el[0] = other.m_el[0];
m_el[1] = other.m_el[1];
m_el[2] = other.m_el[2];
}
-
+ /** @brief Assignment Operator */
SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& other)
{
m_el[0] = other.m_el[0];
@@ -63,34 +66,45 @@ class btMatrix3x3 {
return *this;
}
+ /** @brief Get a column of the matrix as a vector
+ * @param i Column number 0 indexed */
SIMD_FORCE_INLINE btVector3 getColumn(int i) const
{
return btVector3(m_el[0][i],m_el[1][i],m_el[2][i]);
}
-
+ /** @brief Get a row of the matrix as a vector
+ * @param i Row number 0 indexed */
SIMD_FORCE_INLINE const btVector3& getRow(int i) const
{
+ btFullAssert(0 <= i && i < 3);
return m_el[i];
}
-
+ /** @brief Get a mutable reference to a row of the matrix as a vector
+ * @param i Row number 0 indexed */
SIMD_FORCE_INLINE btVector3& operator[](int i)
{
btFullAssert(0 <= i && i < 3);
return m_el[i];
}
+ /** @brief Get a const reference to a row of the matrix as a vector
+ * @param i Row number 0 indexed */
SIMD_FORCE_INLINE const btVector3& operator[](int i) const
{
btFullAssert(0 <= i && i < 3);
return m_el[i];
}
+ /** @brief Multiply by the target matrix on the right
+ * @param m Rotation matrix to be applied
+ * Equivilant to this = this * m */
btMatrix3x3& operator*=(const btMatrix3x3& m);
-
+ /** @brief Set from a carray of btScalars
+ * @param m A pointer to the beginning of an array of 9 btScalars */
void setFromOpenGLSubMatrix(const btScalar *m)
{
m_el[0].setValue(m[0],m[4],m[8]);
@@ -98,7 +112,16 @@ class btMatrix3x3 {
m_el[2].setValue(m[2],m[6],m[10]);
}
-
+ /** @brief Set the values of the matrix explicitly (row major)
+ * @param xx Top left
+ * @param xy Top Middle
+ * @param xz Top Right
+ * @param yx Middle Left
+ * @param yy Middle Middle
+ * @param yz Middle Right
+ * @param zx Bottom Left
+ * @param zy Bottom Middle
+ * @param zz Bottom Right*/
void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz,
const btScalar& yx, const btScalar& yy, const btScalar& yz,
const btScalar& zx, const btScalar& zy, const btScalar& zz)
@@ -107,7 +130,9 @@ class btMatrix3x3 {
m_el[1].setValue(yx,yy,yz);
m_el[2].setValue(zx,zy,zz);
}
-
+
+ /** @brief Set the matrix from a quaternion
+ * @param q The Quaternion to match */
void setRotation(const btQuaternion& q)
{
btScalar d = q.length2();
@@ -123,35 +148,27 @@ class btMatrix3x3 {
}
-
+ /** @brief Set the matrix from euler angles using YPR around YXZ respectively
+ * @param yaw Yaw about Y axis
+ * @param pitch Pitch about X axis
+ * @param roll Roll about Z axis
+ */
void setEulerYPR(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
{
-
- btScalar cy(btCos(yaw));
- btScalar sy(btSin(yaw));
- btScalar cp(btCos(pitch));
- btScalar sp(btSin(pitch));
- btScalar cr(btCos(roll));
- btScalar sr(btSin(roll));
- btScalar cc = cy * cr;
- btScalar cs = cy * sr;
- btScalar sc = sy * cr;
- btScalar ss = sy * sr;
- setValue(cc - sp * ss, -cs - sp * sc, -sy * cp,
- cp * sr, cp * cr, -sp,
- sc + sp * cs, -ss + sp * cc, cy * cp);
-
+ setEulerZYX(roll, pitch, yaw);
}
- /**
- * setEulerZYX
- * @param euler a const reference to a btVector3 of euler angles
+ /** @brief Set the matrix from euler angles YPR around ZYX axes
+ * @param eulerX Roll about X axis
+ * @param eulerY Pitch around Y axis
+ * @param eulerZ Yaw aboud Z axis
+ *
* These angles are used to produce a rotation matrix. The euler
* angles are applied in ZYX order. I.e a vector is first rotated
* about X then Y and then Z
**/
-
- void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) {
+ void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) {
+ ///@todo proposed to reverse this since it's labeled zyx but takes arguments xyz and it will match all other parts of the code
btScalar ci ( btCos(eulerX));
btScalar cj ( btCos(eulerY));
btScalar ch ( btCos(eulerZ));
@@ -168,13 +185,24 @@ class btMatrix3x3 {
-sj, cj * si, cj * ci);
}
+ /**@brief Set the matrix to the identity */
void setIdentity()
{
setValue(btScalar(1.0), btScalar(0.0), btScalar(0.0),
btScalar(0.0), btScalar(1.0), btScalar(0.0),
btScalar(0.0), btScalar(0.0), btScalar(1.0));
}
-
+
+ static const btMatrix3x3& getIdentity()
+ {
+ static const btMatrix3x3 identityMatrix(btScalar(1.0), btScalar(0.0), btScalar(0.0),
+ btScalar(0.0), btScalar(1.0), btScalar(0.0),
+ btScalar(0.0), btScalar(0.0), btScalar(1.0));
+ return identityMatrix;
+ }
+
+ /**@brief Fill the values of the matrix into a 9 element array
+ * @param m The array to be filled */
void getOpenGLSubMatrix(btScalar *m) const
{
m[0] = btScalar(m_el[0].x());
@@ -191,6 +219,8 @@ class btMatrix3x3 {
m[11] = btScalar(0.0);
}
+ /**@brief Get the matrix represented as a quaternion
+ * @param q The quaternion which will be set */
void getRotation(btQuaternion& q) const
{
btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z();
@@ -224,35 +254,102 @@ class btMatrix3x3 {
}
q.setValue(temp[0],temp[1],temp[2],temp[3]);
}
-
- void getEuler(btScalar& yaw, btScalar& pitch, btScalar& roll) const
+
+ /**@brief Get the matrix represented as euler angles around YXZ, roundtrip with setEulerYPR
+ * @param yaw Yaw around Y axis
+ * @param pitch Pitch around X axis
+ * @param roll around Z axis */
+ void getEulerYPR(btScalar& yaw, btScalar& pitch, btScalar& roll) const
{
- if (btScalar(m_el[1].z()) < btScalar(1))
- {
- if (btScalar(m_el[1].z()) > -btScalar(1))
- {
- yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x()));
- pitch = btScalar(btAsin(-m_el[1].y()));
- roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z()));
- }
- else
- {
- yaw = btScalar(-btAtan2(-m_el[0].y(), m_el[0].z()));
- pitch = SIMD_HALF_PI;
- roll = btScalar(0.0);
- }
- }
- else
+ // first use the normal calculus
+ yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x()));
+ pitch = btScalar(btAsin(-m_el[2].x()));
+ roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z()));
+
+ // on pitch = +/-HalfPI
+ if (btFabs(pitch)==SIMD_HALF_PI)
{
- yaw = btScalar(btAtan2(-m_el[0].y(), m_el[0].z()));
- pitch = -SIMD_HALF_PI;
- roll = btScalar(0.0);
+ if (yaw>0)
+ yaw-=SIMD_PI;
+ else
+ yaw+=SIMD_PI;
+
+ if (roll>0)
+ roll-=SIMD_PI;
+ else
+ roll+=SIMD_PI;
}
- }
-
-
+ };
+
+
+ /**@brief Get the matrix represented as euler angles around ZYX
+ * @param yaw Yaw around X axis
+ * @param pitch Pitch around Y axis
+ * @param roll around X axis
+ * @param solution_number Which solution of two possible solutions ( 1 or 2) are possible values*/
+ void getEulerZYX(btScalar& yaw, btScalar& pitch, btScalar& roll, unsigned int solution_number = 1) const
+ {
+ struct Euler{btScalar yaw, pitch, roll;};
+ Euler euler_out;
+ Euler euler_out2; //second solution
+ //get the pointer to the raw data
+
+ // Check that pitch is not at a singularity
+ if (btFabs(m_el[2].x()) >= 1)
+ {
+ euler_out.yaw = 0;
+ euler_out2.yaw = 0;
+ // From difference of angles formula
+ btScalar delta = btAtan2(m_el[0].x(),m_el[0].z());
+ if (m_el[2].x() > 0) //gimbal locked up
+ {
+ euler_out.pitch = SIMD_PI / btScalar(2.0);
+ euler_out2.pitch = SIMD_PI / btScalar(2.0);
+ euler_out.roll = euler_out.pitch + delta;
+ euler_out2.roll = euler_out.pitch + delta;
+ }
+ else // gimbal locked down
+ {
+ euler_out.pitch = -SIMD_PI / btScalar(2.0);
+ euler_out2.pitch = -SIMD_PI / btScalar(2.0);
+ euler_out.roll = -euler_out.pitch + delta;
+ euler_out2.roll = -euler_out.pitch + delta;
+ }
+ }
+ else
+ {
+ euler_out.pitch = - btAsin(m_el[2].x());
+ euler_out2.pitch = SIMD_PI - euler_out.pitch;
+
+ euler_out.roll = btAtan2(m_el[2].y()/btCos(euler_out.pitch),
+ m_el[2].z()/btCos(euler_out.pitch));
+ euler_out2.roll = btAtan2(m_el[2].y()/btCos(euler_out2.pitch),
+ m_el[2].z()/btCos(euler_out2.pitch));
+
+ euler_out.yaw = btAtan2(m_el[1].x()/btCos(euler_out.pitch),
+ m_el[0].x()/btCos(euler_out.pitch));
+ euler_out2.yaw = btAtan2(m_el[1].x()/btCos(euler_out2.pitch),
+ m_el[0].x()/btCos(euler_out2.pitch));
+ }
+
+ if (solution_number == 1)
+ {
+ yaw = euler_out.yaw;
+ pitch = euler_out.pitch;
+ roll = euler_out.roll;
+ }
+ else
+ {
+ yaw = euler_out2.yaw;
+ pitch = euler_out2.pitch;
+ roll = euler_out2.roll;
+ }
+ }
+
+ /**@brief Create a scaled copy of the matrix
+ * @param s Scaling vector The elements of the vector will scale each column */
btMatrix3x3 scaled(const btVector3& s) const
{
@@ -261,10 +358,15 @@ class btMatrix3x3 {
m_el[2].x() * s.x(), m_el[2].y() * s.y(), m_el[2].z() * s.z());
}
+ /**@brief Return the determinant of the matrix */
btScalar determinant() const;
+ /**@brief Return the adjoint of the matrix */
btMatrix3x3 adjoint() const;
+ /**@brief Return the matrix with all values non negative */
btMatrix3x3 absolute() const;
+ /**@brief Return the transpose of the matrix */
btMatrix3x3 transpose() const;
+ /**@brief Return the inverse of the matrix */
btMatrix3x3 inverse() const;
btMatrix3x3 transposeTimes(const btMatrix3x3& m) const;
@@ -284,12 +386,15 @@ class btMatrix3x3 {
}
- ///diagonalizes this matrix by the Jacobi method. rot stores the rotation
- ///from the coordinate system in which the matrix is diagonal to the original
- ///coordinate system, i.e., old_this = rot * new_this * rot^T. The iteration
- ///stops when all off-diagonal elements are less than the threshold multiplied
- ///by the sum of the absolute values of the diagonal, or when maxSteps have
- ///been executed. Note that this matrix is assumed to be symmetric.
+ /**@brief diagonalizes this matrix by the Jacobi method.
+ * @param rot stores the rotation from the coordinate system in which the matrix is diagonal to the original
+ * coordinate system, i.e., old_this = rot * new_this * rot^T.
+ * @param threshold See iteration
+ * @param iteration The iteration stops when all off-diagonal elements are less than the threshold multiplied
+ * by the sum of the absolute values of the diagonal, or when maxSteps have been executed.
+ *
+ * Note that this matrix is assumed to be symmetric.
+ */
void diagonalize(btMatrix3x3& rot, btScalar threshold, int maxSteps)
{
rot.setIdentity();
@@ -371,11 +476,18 @@ class btMatrix3x3 {
protected:
+ /**@brief Calculate the matrix cofactor
+ * @param r1 The first row to use for calculating the cofactor
+ * @param c1 The first column to use for calculating the cofactor
+ * @param r1 The second row to use for calculating the cofactor
+ * @param c1 The second column to use for calculating the cofactor
+ * See http://en.wikipedia.org/wiki/Cofactor_(linear_algebra) for more details
+ */
btScalar cofac(int r1, int c1, int r2, int c2) const
{
return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1];
}
-
+ ///Data storage for the matrix, each vector is a row of the matrix
btVector3 m_el[3];
};
@@ -494,6 +606,8 @@ class btMatrix3x3 {
}
*/
+/**@brief Equality operator between two matrices
+ * It will test all elements are equal. */
SIMD_FORCE_INLINE bool operator==(const btMatrix3x3& m1, const btMatrix3x3& m2)
{
return ( m1[0][0] == m2[0][0] && m1[1][0] == m2[1][0] && m1[2][0] == m2[2][0] &&
diff --git a/extern/bullet2/src/LinearMath/btQuadWord.h b/extern/bullet2/src/LinearMath/btQuadWord.h
index 2e80fc2ca47..c657afd2bb1 100644
--- a/extern/bullet2/src/LinearMath/btQuadWord.h
+++ b/extern/bullet2/src/LinearMath/btQuadWord.h
@@ -18,121 +18,159 @@ subject to the following restrictions:
#include "btScalar.h"
#include "btMinMax.h"
-#include <math.h>
+#if defined (__CELLOS_LV2) && defined (__SPU__)
+#include <altivec.h>
+#endif
-///The btQuadWordStorage class is base class for btVector3 and btQuaternion.
-///Some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword. todo: look into this
-///ATTRIBUTE_ALIGNED16(class) btQuadWordStorage
-class btQuadWordStorage
+/**@brief The btQuadWord class is base class for btVector3 and btQuaternion.
+ * Some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword.
+ */
+#ifndef USE_LIBSPE2
+ATTRIBUTE_ALIGNED16(class) btQuadWord
+#else
+class btQuadWord
+#endif
{
protected:
- btScalar m_x;
- btScalar m_y;
- btScalar m_z;
- btScalar m_unusedW;
-
+#if defined (__SPU__) && defined (__CELLOS_LV2__)
+ union {
+ vec_float4 mVec128;
+ btScalar m_floats[4];
+ };
public:
+ vec_float4 get128() const
+ {
+ return mVec128;
+ }
+protected:
+#else //__CELLOS_LV2__ __SPU__
+ btScalar m_floats[4];
+#endif //__CELLOS_LV2__ __SPU__
-};
-
-
-///btQuadWord is base-class for vectors, points
-class btQuadWord : public btQuadWordStorage
-{
public:
-
-// SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_x)[i]; }
-// SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_x)[i]; }
-
- SIMD_FORCE_INLINE const btScalar& getX() const { return m_x; }
-
- SIMD_FORCE_INLINE const btScalar& getY() const { return m_y; }
-
- SIMD_FORCE_INLINE const btScalar& getZ() const { return m_z; }
-
- SIMD_FORCE_INLINE void setX(btScalar x) { m_x = x;};
-
- SIMD_FORCE_INLINE void setY(btScalar y) { m_y = y;};
-
- SIMD_FORCE_INLINE void setZ(btScalar z) { m_z = z;};
-
- SIMD_FORCE_INLINE void setW(btScalar w) { m_unusedW = w;};
-
- SIMD_FORCE_INLINE const btScalar& x() const { return m_x; }
-
- SIMD_FORCE_INLINE const btScalar& y() const { return m_y; }
-
- SIMD_FORCE_INLINE const btScalar& z() const { return m_z; }
-
- SIMD_FORCE_INLINE const btScalar& w() const { return m_unusedW; }
-
-
- SIMD_FORCE_INLINE operator btScalar *() { return &m_x; }
- SIMD_FORCE_INLINE operator const btScalar *() const { return &m_x; }
-
-
-
+
+
+ /**@brief Return the x value */
+ SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; }
+ /**@brief Return the y value */
+ SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; }
+ /**@brief Return the z value */
+ SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; }
+ /**@brief Set the x value */
+ SIMD_FORCE_INLINE void setX(btScalar x) { m_floats[0] = x;};
+ /**@brief Set the y value */
+ SIMD_FORCE_INLINE void setY(btScalar y) { m_floats[1] = y;};
+ /**@brief Set the z value */
+ SIMD_FORCE_INLINE void setZ(btScalar z) { m_floats[2] = z;};
+ /**@brief Set the w value */
+ SIMD_FORCE_INLINE void setW(btScalar w) { m_floats[3] = w;};
+ /**@brief Return the x value */
+ SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; }
+ /**@brief Return the y value */
+ SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; }
+ /**@brief Return the z value */
+ SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; }
+ /**@brief Return the w value */
+ SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; }
+
+ //SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; }
+ //SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; }
+ ///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons.
+ SIMD_FORCE_INLINE operator btScalar *() { return &m_floats[0]; }
+ SIMD_FORCE_INLINE operator const btScalar *() const { return &m_floats[0]; }
+
+ SIMD_FORCE_INLINE bool operator==(const btQuadWord& other) const
+ {
+ return ((m_floats[3]==other.m_floats[3]) && (m_floats[2]==other.m_floats[2]) && (m_floats[1]==other.m_floats[1]) && (m_floats[0]==other.m_floats[0]));
+ }
+
+ SIMD_FORCE_INLINE bool operator!=(const btQuadWord& other) const
+ {
+ return !(*this == other);
+ }
+
+ /**@brief Set x,y,z and zero w
+ * @param x Value of x
+ * @param y Value of y
+ * @param z Value of z
+ */
SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z)
{
- m_x=x;
- m_y=y;
- m_z=z;
- m_unusedW = 0.f;
+ m_floats[0]=x;
+ m_floats[1]=y;
+ m_floats[2]=z;
+ m_floats[3] = 0.f;
}
/* void getValue(btScalar *m) const
{
- m[0] = m_x;
- m[1] = m_y;
- m[2] = m_z;
+ m[0] = m_floats[0];
+ m[1] = m_floats[1];
+ m[2] = m_floats[2];
}
*/
+/**@brief Set the values
+ * @param x Value of x
+ * @param y Value of y
+ * @param z Value of z
+ * @param w Value of w
+ */
SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
{
- m_x=x;
- m_y=y;
- m_z=z;
- m_unusedW=w;
+ m_floats[0]=x;
+ m_floats[1]=y;
+ m_floats[2]=z;
+ m_floats[3]=w;
}
-
+ /**@brief No initialization constructor */
SIMD_FORCE_INLINE btQuadWord()
- // :m_x(btScalar(0.)),m_y(btScalar(0.)),m_z(btScalar(0.)),m_unusedW(btScalar(0.))
- {
- }
-
- SIMD_FORCE_INLINE btQuadWord(const btQuadWordStorage& q)
+ // :m_floats[0](btScalar(0.)),m_floats[1](btScalar(0.)),m_floats[2](btScalar(0.)),m_floats[3](btScalar(0.))
{
- *((btQuadWordStorage*)this) = q;
}
-
+
+ /**@brief Three argument constructor (zeros w)
+ * @param x Value of x
+ * @param y Value of y
+ * @param z Value of z
+ */
SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z)
{
- m_x = x, m_y = y, m_z = z, m_unusedW = 0.0f;
+ m_floats[0] = x, m_floats[1] = y, m_floats[2] = z, m_floats[3] = 0.0f;
}
+/**@brief Initializing constructor
+ * @param x Value of x
+ * @param y Value of y
+ * @param z Value of z
+ * @param w Value of w
+ */
SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
{
- m_x = x, m_y = y, m_z = z, m_unusedW = w;
+ m_floats[0] = x, m_floats[1] = y, m_floats[2] = z, m_floats[3] = w;
}
-
+ /**@brief Set each element to the max of the current values and the values of another btQuadWord
+ * @param other The other btQuadWord to compare with
+ */
SIMD_FORCE_INLINE void setMax(const btQuadWord& other)
{
- btSetMax(m_x, other.m_x);
- btSetMax(m_y, other.m_y);
- btSetMax(m_z, other.m_z);
- btSetMax(m_unusedW, other.m_unusedW);
+ btSetMax(m_floats[0], other.m_floats[0]);
+ btSetMax(m_floats[1], other.m_floats[1]);
+ btSetMax(m_floats[2], other.m_floats[2]);
+ btSetMax(m_floats[3], other.m_floats[3]);
}
-
+ /**@brief Set each element to the min of the current values and the values of another btQuadWord
+ * @param other The other btQuadWord to compare with
+ */
SIMD_FORCE_INLINE void setMin(const btQuadWord& other)
{
- btSetMin(m_x, other.m_x);
- btSetMin(m_y, other.m_y);
- btSetMin(m_z, other.m_z);
- btSetMin(m_unusedW, other.m_unusedW);
+ btSetMin(m_floats[0], other.m_floats[0]);
+ btSetMin(m_floats[1], other.m_floats[1]);
+ btSetMin(m_floats[2], other.m_floats[2]);
+ btSetMin(m_floats[3], other.m_floats[3]);
}
diff --git a/extern/bullet2/src/LinearMath/btQuaternion.h b/extern/bullet2/src/LinearMath/btQuaternion.h
index 264751b33e7..cbeca2681cc 100644
--- a/extern/bullet2/src/LinearMath/btQuaternion.h
+++ b/extern/bullet2/src/LinearMath/btQuaternion.h
@@ -17,39 +17,56 @@ subject to the following restrictions:
#ifndef SIMD__QUATERNION_H_
#define SIMD__QUATERNION_H_
+
#include "btVector3.h"
+#include "btQuadWord.h"
-///The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatrix3x3, btVector3 and btTransform.
+/**@brief The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatrix3x3, btVector3 and btTransform. */
class btQuaternion : public btQuadWord {
public:
+ /**@brief No initialization constructor */
btQuaternion() {}
// template <typename btScalar>
// explicit Quaternion(const btScalar *v) : Tuple4<btScalar>(v) {}
-
+ /**@brief Constructor from scalars */
btQuaternion(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w)
: btQuadWord(x, y, z, w)
{}
-
+ /**@brief Axis angle Constructor
+ * @param axis The axis which the rotation is around
+ * @param angle The magnitude of the rotation around the angle (Radians) */
btQuaternion(const btVector3& axis, const btScalar& angle)
{
setRotation(axis, angle);
}
-
+ /**@brief Constructor from Euler angles
+ * @param yaw Angle around Y unless BT_EULER_DEFAULT_ZYX defined then Z
+ * @param pitch Angle around X unless BT_EULER_DEFAULT_ZYX defined then Y
+ * @param roll Angle around Z unless BT_EULER_DEFAULT_ZYX defined then X */
btQuaternion(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
{
+#ifndef BT_EULER_DEFAULT_ZYX
setEuler(yaw, pitch, roll);
+#else
+ setEulerZYX(yaw, pitch, roll);
+#endif
}
-
+ /**@brief Set the rotation using axis angle notation
+ * @param axis The axis around which to rotate
+ * @param angle The magnitude of the rotation in Radians */
void setRotation(const btVector3& axis, const btScalar& angle)
{
btScalar d = axis.length();
- assert(d != btScalar(0.0));
+ btAssert(d != btScalar(0.0));
btScalar s = btSin(angle * btScalar(0.5)) / d;
setValue(axis.x() * s, axis.y() * s, axis.z() * s,
btCos(angle * btScalar(0.5)));
}
-
+ /**@brief Set the quaternion using Euler angles
+ * @param yaw Angle around Y
+ * @param pitch Angle around X
+ * @param roll Angle around Z */
void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
{
btScalar halfYaw = btScalar(yaw) * btScalar(0.5);
@@ -66,122 +83,165 @@ public:
sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
}
-
- btQuaternion& operator+=(const btQuaternion& q)
+ /**@brief Set the quaternion using euler angles
+ * @param yaw Angle around Z
+ * @param pitch Angle around Y
+ * @param roll Angle around X */
+ void setEulerZYX(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
{
- m_x += q.x(); m_y += q.y(); m_z += q.z(); m_unusedW += q.m_unusedW;
+ btScalar halfYaw = btScalar(yaw) * btScalar(0.5);
+ btScalar halfPitch = btScalar(pitch) * btScalar(0.5);
+ btScalar halfRoll = btScalar(roll) * btScalar(0.5);
+ btScalar cosYaw = btCos(halfYaw);
+ btScalar sinYaw = btSin(halfYaw);
+ btScalar cosPitch = btCos(halfPitch);
+ btScalar sinPitch = btSin(halfPitch);
+ btScalar cosRoll = btCos(halfRoll);
+ btScalar sinRoll = btSin(halfRoll);
+ setValue(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, //x
+ cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, //y
+ cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, //z
+ cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); //formerly yzx
+ }
+ /**@brief Add two quaternions
+ * @param q The quaternion to add to this one */
+ SIMD_FORCE_INLINE btQuaternion& operator+=(const btQuaternion& q)
+ {
+ m_floats[0] += q.x(); m_floats[1] += q.y(); m_floats[2] += q.z(); m_floats[3] += q.m_floats[3];
return *this;
}
+ /**@brief Subtract out a quaternion
+ * @param q The quaternion to subtract from this one */
btQuaternion& operator-=(const btQuaternion& q)
{
- m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_unusedW -= q.m_unusedW;
+ m_floats[0] -= q.x(); m_floats[1] -= q.y(); m_floats[2] -= q.z(); m_floats[3] -= q.m_floats[3];
return *this;
}
+ /**@brief Scale this quaternion
+ * @param s The scalar to scale by */
btQuaternion& operator*=(const btScalar& s)
{
- m_x *= s; m_y *= s; m_z *= s; m_unusedW *= s;
+ m_floats[0] *= s; m_floats[1] *= s; m_floats[2] *= s; m_floats[3] *= s;
return *this;
}
-
+ /**@brief Multiply this quaternion by q on the right
+ * @param q The other quaternion
+ * Equivilant to this = this * q */
btQuaternion& operator*=(const btQuaternion& q)
{
- setValue(m_unusedW * q.x() + m_x * q.m_unusedW + m_y * q.z() - m_z * q.y(),
- m_unusedW * q.y() + m_y * q.m_unusedW + m_z * q.x() - m_x * q.z(),
- m_unusedW * q.z() + m_z * q.m_unusedW + m_x * q.y() - m_y * q.x(),
- m_unusedW * q.m_unusedW - m_x * q.x() - m_y * q.y() - m_z * q.z());
+ setValue(m_floats[3] * q.x() + m_floats[0] * q.m_floats[3] + m_floats[1] * q.z() - m_floats[2] * q.y(),
+ m_floats[3] * q.y() + m_floats[1] * q.m_floats[3] + m_floats[2] * q.x() - m_floats[0] * q.z(),
+ m_floats[3] * q.z() + m_floats[2] * q.m_floats[3] + m_floats[0] * q.y() - m_floats[1] * q.x(),
+ m_floats[3] * q.m_floats[3] - m_floats[0] * q.x() - m_floats[1] * q.y() - m_floats[2] * q.z());
return *this;
}
-
+ /**@brief Return the dot product between this quaternion and another
+ * @param q The other quaternion */
btScalar dot(const btQuaternion& q) const
{
- return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_unusedW * q.m_unusedW;
+ return m_floats[0] * q.x() + m_floats[1] * q.y() + m_floats[2] * q.z() + m_floats[3] * q.m_floats[3];
}
+ /**@brief Return the length squared of the quaternion */
btScalar length2() const
{
return dot(*this);
}
+ /**@brief Return the length of the quaternion */
btScalar length() const
{
return btSqrt(length2());
}
+ /**@brief Normalize the quaternion
+ * Such that x^2 + y^2 + z^2 +w^2 = 1 */
btQuaternion& normalize()
{
return *this /= length();
}
+ /**@brief Return a scaled version of this quaternion
+ * @param s The scale factor */
SIMD_FORCE_INLINE btQuaternion
operator*(const btScalar& s) const
{
- return btQuaternion(x() * s, y() * s, z() * s, m_unusedW * s);
+ return btQuaternion(x() * s, y() * s, z() * s, m_floats[3] * s);
}
-
+ /**@brief Return an inversely scaled versionof this quaternion
+ * @param s The inverse scale factor */
btQuaternion operator/(const btScalar& s) const
{
- assert(s != btScalar(0.0));
+ btAssert(s != btScalar(0.0));
return *this * (btScalar(1.0) / s);
}
-
+ /**@brief Inversely scale this quaternion
+ * @param s The scale factor */
btQuaternion& operator/=(const btScalar& s)
{
- assert(s != btScalar(0.0));
+ btAssert(s != btScalar(0.0));
return *this *= btScalar(1.0) / s;
}
-
+ /**@brief Return a normalized version of this quaternion */
btQuaternion normalized() const
{
return *this / length();
}
-
+ /**@brief Return the angle between this quaternion and the other
+ * @param q The other quaternion */
btScalar angle(const btQuaternion& q) const
{
btScalar s = btSqrt(length2() * q.length2());
- assert(s != btScalar(0.0));
+ btAssert(s != btScalar(0.0));
return btAcos(dot(q) / s);
}
-
+ /**@brief Return the angle of rotation represented by this quaternion */
btScalar getAngle() const
{
- btScalar s = btScalar(2.) * btAcos(m_unusedW);
+ btScalar s = btScalar(2.) * btAcos(m_floats[3]);
return s;
}
-
+ /**@brief Return the inverse of this quaternion */
btQuaternion inverse() const
{
- return btQuaternion(-m_x, -m_y, -m_z, m_unusedW);
+ return btQuaternion(-m_floats[0], -m_floats[1], -m_floats[2], m_floats[3]);
}
+ /**@brief Return the sum of this quaternion and the other
+ * @param q2 The other quaternion */
SIMD_FORCE_INLINE btQuaternion
operator+(const btQuaternion& q2) const
{
const btQuaternion& q1 = *this;
- return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_unusedW + q2.m_unusedW);
+ return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_floats[3] + q2.m_floats[3]);
}
+ /**@brief Return the difference between this quaternion and the other
+ * @param q2 The other quaternion */
SIMD_FORCE_INLINE btQuaternion
operator-(const btQuaternion& q2) const
{
const btQuaternion& q1 = *this;
- return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_unusedW - q2.m_unusedW);
+ return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_floats[3] - q2.m_floats[3]);
}
+ /**@brief Return the negative of this quaternion
+ * This simply negates each element */
SIMD_FORCE_INLINE btQuaternion operator-() const
{
const btQuaternion& q2 = *this;
- return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_unusedW);
+ return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_floats[3]);
}
-
+ /**@todo document this and it's use */
SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const
{
btQuaternion diff,sum;
@@ -192,6 +252,10 @@ public:
return (-qd);
}
+ /**@brief Return the quaternion which is the result of Spherical Linear Interpolation between this and the other quaternion
+ * @param q The other quaternion to interpolate with
+ * @param t The ratio between this and q to interpolate. If t = 0 the result is this, if t=1 the result is q.
+ * Slerp interpolates assuming constant velocity. */
btQuaternion slerp(const btQuaternion& q, const btScalar& t) const
{
btScalar theta = angle(q);
@@ -200,10 +264,10 @@ public:
btScalar d = btScalar(1.0) / btSin(theta);
btScalar s0 = btSin((btScalar(1.0) - t) * theta);
btScalar s1 = btSin(t * theta);
- return btQuaternion((m_x * s0 + q.x() * s1) * d,
- (m_y * s0 + q.y() * s1) * d,
- (m_z * s0 + q.z() * s1) * d,
- (m_unusedW * s0 + q.m_unusedW * s1) * d);
+ return btQuaternion((m_floats[0] * s0 + q.x() * s1) * d,
+ (m_floats[1] * s0 + q.y() * s1) * d,
+ (m_floats[2] * s0 + q.z() * s1) * d,
+ (m_floats[3] * s0 + q.m_floats[3] * s1) * d);
}
else
{
@@ -211,13 +275,19 @@ public:
}
}
- SIMD_FORCE_INLINE const btScalar& getW() const { return m_unusedW; }
+ static const btQuaternion& getIdentity()
+ {
+ static const btQuaternion identityQuat(btScalar(0.),btScalar(0.),btScalar(0.),btScalar(1.));
+ return identityQuat;
+ }
+
+ SIMD_FORCE_INLINE const btScalar& getW() const { return m_floats[3]; }
};
-
+/**@brief Return the negative of a quaternion */
SIMD_FORCE_INLINE btQuaternion
operator-(const btQuaternion& q)
{
@@ -226,7 +296,7 @@ operator-(const btQuaternion& q)
-
+/**@brief Return the product of two quaternions */
SIMD_FORCE_INLINE btQuaternion
operator*(const btQuaternion& q1, const btQuaternion& q2) {
return btQuaternion(q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(),
@@ -253,6 +323,7 @@ operator*(const btVector3& w, const btQuaternion& q)
-w.x() * q.x() - w.y() * q.y() - w.z() * q.z());
}
+/**@brief Calculate the dot product between two quaternions */
SIMD_FORCE_INLINE btScalar
dot(const btQuaternion& q1, const btQuaternion& q2)
{
@@ -260,25 +331,32 @@ dot(const btQuaternion& q1, const btQuaternion& q2)
}
+/**@brief Return the length of a quaternion */
SIMD_FORCE_INLINE btScalar
length(const btQuaternion& q)
{
return q.length();
}
+/**@brief Return the angle between two quaternions*/
SIMD_FORCE_INLINE btScalar
angle(const btQuaternion& q1, const btQuaternion& q2)
{
return q1.angle(q2);
}
-
+/**@brief Return the inverse of a quaternion*/
SIMD_FORCE_INLINE btQuaternion
inverse(const btQuaternion& q)
{
return q.inverse();
}
+/**@brief Return the result of spherical linear interpolation betwen two quaternions
+ * @param q1 The first quaternion
+ * @param q2 The second quaternion
+ * @param t The ration between q1 and q2. t = 0 return q1, t=1 returns q2
+ * Slerp assumes constant velocity between positions. */
SIMD_FORCE_INLINE btQuaternion
slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t)
{
diff --git a/extern/bullet2/src/LinearMath/btQuickprof.cpp b/extern/bullet2/src/LinearMath/btQuickprof.cpp
index e5b1196149b..fa45d02b3d3 100644
--- a/extern/bullet2/src/LinearMath/btQuickprof.cpp
+++ b/extern/bullet2/src/LinearMath/btQuickprof.cpp
@@ -110,7 +110,7 @@ void CProfileNode::Reset( void )
{
TotalCalls = 0;
TotalTime = 0.0f;
- gProfileClock.reset();
+
if ( Child ) {
Child->Reset();
@@ -251,6 +251,7 @@ void CProfileManager::Stop_Profile( void )
*=============================================================================================*/
void CProfileManager::Reset( void )
{
+ gProfileClock.reset();
Root.Reset();
Root.Call();
FrameCounter = 0;
@@ -278,5 +279,68 @@ float CProfileManager::Get_Time_Since_Reset( void )
return (float)time / Profile_Get_Tick_Rate();
}
+#include <stdio.h>
+
+void CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spacing)
+{
+ profileIterator->First();
+ if (profileIterator->Is_Done())
+ return;
+
+ float accumulated_time=0,parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
+ int i;
+ int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
+ for (i=0;i<spacing;i++) printf(".");
+ printf("----------------------------------\n");
+ for (i=0;i<spacing;i++) printf(".");
+ printf("Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time );
+ float totalTime = 0.f;
+
+
+ int numChildren = 0;
+
+ for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next())
+ {
+ numChildren++;
+ float current_total_time = profileIterator->Get_Current_Total_Time();
+ accumulated_time += current_total_time;
+ float fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
+ {
+ int i; for (i=0;i<spacing;i++) printf(".");
+ }
+ printf("%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)\n",i, profileIterator->Get_Current_Name(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls());
+ totalTime += current_total_time;
+ //recurse into children
+ }
+
+ if (parent_time < accumulated_time)
+ {
+ printf("what's wrong\n");
+ }
+ for (i=0;i<spacing;i++) printf(".");
+ printf("%s (%.3f %%) :: %.3f ms\n", "Unaccounted:",parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
+
+ for (i=0;i<numChildren;i++)
+ {
+ profileIterator->Enter_Child(i);
+ dumpRecursive(profileIterator,spacing+3);
+ profileIterator->Enter_Parent();
+ }
+}
+
+
+
+void CProfileManager::dumpAll()
+{
+ CProfileIterator* profileIterator = 0;
+ profileIterator = CProfileManager::Get_Iterator();
+
+ dumpRecursive(profileIterator,0);
+
+ CProfileManager::Release_Iterator(profileIterator);
+}
+
+
+
#endif //USE_BT_CLOCK
diff --git a/extern/bullet2/src/LinearMath/btQuickprof.h b/extern/bullet2/src/LinearMath/btQuickprof.h
index b033940ca5c..f8d47c36861 100644
--- a/extern/bullet2/src/LinearMath/btQuickprof.h
+++ b/extern/bullet2/src/LinearMath/btQuickprof.h
@@ -10,14 +10,20 @@
// Credits: The Clock class was inspired by the Timer classes in
// Ogre (www.ogre3d.org).
+
+
#ifndef QUICK_PROF_H
#define QUICK_PROF_H
+//To disable built-in profiling, please comment out next line
+//#define BT_NO_PROFILE 1
+#ifndef BT_NO_PROFILE
+
#include "btScalar.h"
#include "LinearMath/btAlignedAllocator.h"
#include <new>
-//To disable built-in profiling, please comment out next line
-//#define BT_NO_PROFILE 1
+
+
//if you don't need btClock, you can comment next line
@@ -321,6 +327,10 @@ public:
}
static void Release_Iterator( CProfileIterator * iterator ) { delete ( iterator); }
+ static void dumpRecursive(CProfileIterator* profileIterator, int spacing);
+
+ static void dumpAll();
+
private:
static CProfileNode Root;
static CProfileNode * CurrentNode;
@@ -344,12 +354,14 @@ public:
}
};
-#if !defined(BT_NO_PROFILE)
+
#define BT_PROFILE( name ) CProfileSample __profile( name )
+
#else
+
#define BT_PROFILE( name )
-#endif
+#endif //#ifndef BT_NO_PROFILE
diff --git a/extern/bullet2/src/LinearMath/btScalar.h b/extern/bullet2/src/LinearMath/btScalar.h
index e8433405b20..822296164c1 100644
--- a/extern/bullet2/src/LinearMath/btScalar.h
+++ b/extern/bullet2/src/LinearMath/btScalar.h
@@ -18,13 +18,14 @@ subject to the following restrictions:
#define SIMD___SCALAR_H
#include <math.h>
+
#include <stdlib.h>//size_t for MSVC 6.0
#include <cstdlib>
#include <cfloat>
#include <float.h>
-#define BT_BULLET_VERSION 272
+#define BT_BULLET_VERSION 274
inline int btGetVersion()
{
@@ -44,7 +45,7 @@ inline int btGetVersion()
#define ATTRIBUTE_ALIGNED16(a) a
#define ATTRIBUTE_ALIGNED128(a) a
#else
- #define BT_HAS_ALIGNED_ALLOCATOR
+ //#define BT_HAS_ALIGNED_ALLOCATOR
#pragma warning(disable : 4324) // disable padding warning
// #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning.
// #pragma warning(disable:4996) //Turn off warnings about deprecated C routines
@@ -60,12 +61,18 @@ inline int btGetVersion()
#define BT_HAVE_NATIVE_FSEL
#define btFsel(a,b,c) __fsel((a),(b),(c))
#else
+
+#if (defined (WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (BT_USE_DOUBLE_PRECISION))
#define BT_USE_SSE
- #endif
+ #include <emmintrin.h>
+#endif
+
+ #endif//_XBOX
+
#endif //__MINGW32__
#include <assert.h>
-#if defined(DEBUG) || defined (_DEBUG)
+#ifdef BT_DEBUG
#define btAssert assert
#else
#define btAssert(x)
@@ -85,7 +92,11 @@ inline int btGetVersion()
#ifndef assert
#include <assert.h>
#endif
+#ifdef BT_DEBUG
#define btAssert assert
+#else
+ #define btAssert(x)
+#endif
//btFullAssert is optional, slows down a lot
#define btFullAssert(x)
@@ -102,7 +113,11 @@ inline int btGetVersion()
#ifndef assert
#include <assert.h>
#endif
+#ifdef BT_DEBUG
#define btAssert assert
+#else
+ #define btAssert(x)
+#endif
//btFullAssert is optional, slows down a lot
#define btFullAssert(x)
@@ -115,6 +130,9 @@ inline int btGetVersion()
//non-windows systems
#define SIMD_FORCE_INLINE inline
+ ///@todo: check out alignment methods for other platforms/compilers
+ ///#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
+ ///#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
#define ATTRIBUTE_ALIGNED16(a) a
#define ATTRIBUTE_ALIGNED128(a) a
#ifndef assert
@@ -141,10 +159,6 @@ inline int btGetVersion()
/// older compilers (gcc 3.x) and Sun needs double version of sqrt etc.
/// exclude Apple Intel (i's assumed to be a Macbook or new Intel Dual Core Processor)
#if defined (__sun) || defined (__sun__) || defined (__sparc) || (defined (__APPLE__) && ! defined (__i386__))
-/* XXX Need to fix these... needed for SunOS 5.8 */
-#define sinf(a) sin((double)(a))
-#define cosf(a) cos((double)(a))
-#define fabsf(a) fabs((double)(a))
//use slow double float precision operation on those platforms
#ifndef BT_USE_DOUBLE_PRECISION
#define BT_FORCE_DOUBLE_FUNCTIONS
@@ -198,7 +212,7 @@ SIMD_FORCE_INLINE btScalar btSqrt(btScalar y)
tempf = y;
*tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
x = tempf;
- z = y*btScalar(0.5); /* hoist out the ô/2ö */
+ z = y*btScalar(0.5); /* hoist out the “/2” */
x = (btScalar(1.5)*x)-(x*x)*(x*z); /* iteration formula */
x = (btScalar(1.5)*x)-(x*x)*(x*z);
x = (btScalar(1.5)*x)-(x*x)*(x*z);
diff --git a/extern/bullet2/src/LinearMath/btStackAlloc.h b/extern/bullet2/src/LinearMath/btStackAlloc.h
index 050d44bdfe9..397b084877f 100644
--- a/extern/bullet2/src/LinearMath/btStackAlloc.h
+++ b/extern/bullet2/src/LinearMath/btStackAlloc.h
@@ -23,6 +23,7 @@ Nov.2006
#include "btScalar.h" //for btAssert
#include "btAlignedAllocator.h"
+///The btBlock class is an internal structure for the btStackAlloc memory allocator.
struct btBlock
{
btBlock* previous;
diff --git a/extern/bullet2/src/LinearMath/btTransform.h b/extern/bullet2/src/LinearMath/btTransform.h
index a8cdb428100..c4fe33eecd7 100644
--- a/extern/bullet2/src/LinearMath/btTransform.h
+++ b/extern/bullet2/src/LinearMath/btTransform.h
@@ -21,34 +21,39 @@ subject to the following restrictions:
#include "btMatrix3x3.h"
-///The btTransform class supports rigid transforms with only translation and rotation and no scaling/shear.
-///It can be used in combination with btVector3, btQuaternion and btMatrix3x3 linear algebra classes.
+/**@brief The btTransform class supports rigid transforms with only translation and rotation and no scaling/shear.
+ *It can be used in combination with btVector3, btQuaternion and btMatrix3x3 linear algebra classes. */
class btTransform {
public:
-
+ /**@brief No initialization constructor */
btTransform() {}
-
+ /**@brief Constructor from btQuaternion (optional btVector3 )
+ * @param q Rotation from quaternion
+ * @param c Translation from Vector (default 0,0,0) */
explicit SIMD_FORCE_INLINE btTransform(const btQuaternion& q,
const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
: m_basis(q),
m_origin(c)
{}
+ /**@brief Constructor from btMatrix3x3 (optional btVector3)
+ * @param b Rotation from Matrix
+ * @param c Translation from Vector default (0,0,0)*/
explicit SIMD_FORCE_INLINE btTransform(const btMatrix3x3& b,
const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
: m_basis(b),
m_origin(c)
{}
-
+ /**@brief Copy constructor */
SIMD_FORCE_INLINE btTransform (const btTransform& other)
: m_basis(other.m_basis),
m_origin(other.m_origin)
{
}
-
+ /**@brief Assignment Operator */
SIMD_FORCE_INLINE btTransform& operator=(const btTransform& other)
{
m_basis = other.m_basis;
@@ -57,6 +62,10 @@ public:
}
+ /**@brief Set the current transform as the value of the product of two transforms
+ * @param t1 Transform 1
+ * @param t2 Transform 2
+ * This = Transform1 * Transform2 */
SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2) {
m_basis = t1.m_basis * t2.m_basis;
m_origin = t1(t2.m_origin);
@@ -69,7 +78,7 @@ public:
}
*/
-
+/**@brief Return the transform of the vector */
SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const
{
return btVector3(m_basis[0].dot(x) + m_origin.x(),
@@ -77,17 +86,29 @@ public:
m_basis[2].dot(x) + m_origin.z());
}
+ /**@brief Return the transform of the vector */
SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const
{
return (*this)(x);
}
+ /**@brief Return the transform of the btQuaternion */
+ SIMD_FORCE_INLINE btQuaternion operator*(const btQuaternion& q) const
+ {
+ return getRotation() * q;
+ }
+
+ /**@brief Return the basis matrix for the rotation */
SIMD_FORCE_INLINE btMatrix3x3& getBasis() { return m_basis; }
+ /**@brief Return the basis matrix for the rotation */
SIMD_FORCE_INLINE const btMatrix3x3& getBasis() const { return m_basis; }
+ /**@brief Return the origin vector translation */
SIMD_FORCE_INLINE btVector3& getOrigin() { return m_origin; }
+ /**@brief Return the origin vector translation */
SIMD_FORCE_INLINE const btVector3& getOrigin() const { return m_origin; }
+ /**@brief Return a quaternion representing the rotation */
btQuaternion getRotation() const {
btQuaternion q;
m_basis.getRotation(q);
@@ -95,12 +116,16 @@ public:
}
+ /**@brief Set from an array
+ * @param m A pointer to a 15 element array (12 rotation(row major padded on the right by 1), and 3 translation */
void setFromOpenGLMatrix(const btScalar *m)
{
m_basis.setFromOpenGLSubMatrix(m);
m_origin.setValue(m[12],m[13],m[14]);
}
+ /**@brief Fill an array representation
+ * @param m A pointer to a 15 element array (12 rotation(row major padded on the right by 1), and 3 translation */
void getOpenGLMatrix(btScalar *m) const
{
m_basis.getOpenGLSubMatrix(m);
@@ -110,6 +135,8 @@ public:
m[15] = btScalar(1.0);
}
+ /**@brief Set the translational element
+ * @param origin The vector to set the translation to */
SIMD_FORCE_INLINE void setOrigin(const btVector3& origin)
{
m_origin = origin;
@@ -118,26 +145,28 @@ public:
SIMD_FORCE_INLINE btVector3 invXform(const btVector3& inVec) const;
-
+ /**@brief Set the rotational element by btMatrix3x3 */
SIMD_FORCE_INLINE void setBasis(const btMatrix3x3& basis)
{
m_basis = basis;
}
+ /**@brief Set the rotational element by btQuaternion */
SIMD_FORCE_INLINE void setRotation(const btQuaternion& q)
{
m_basis.setRotation(q);
}
-
+ /**@brief Set this transformation to the identity */
void setIdentity()
{
m_basis.setIdentity();
m_origin.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
}
-
+ /**@brief Multiply this Transform by another(this = this * another)
+ * @param t The other transform */
btTransform& operator*=(const btTransform& t)
{
m_origin += m_basis * t.m_origin;
@@ -145,26 +174,32 @@ public:
return *this;
}
+ /**@brief Return the inverse of this transform */
btTransform inverse() const
{
btMatrix3x3 inv = m_basis.transpose();
return btTransform(inv, inv * -m_origin);
}
+ /**@brief Return the inverse of this transform times the other transform
+ * @param t The other transform
+ * return this.inverse() * the other */
btTransform inverseTimes(const btTransform& t) const;
+ /**@brief Return the product of this transform and the other */
btTransform operator*(const btTransform& t) const;
- static btTransform getIdentity()
+ /**@brief Return an identity transform */
+ static const btTransform& getIdentity()
{
- btTransform tr;
- tr.setIdentity();
- return tr;
+ static const btTransform identityTransform(btMatrix3x3::getIdentity());
+ return identityTransform;
}
private:
-
+ ///Storage for the rotation
btMatrix3x3 m_basis;
+ ///Storage for the translation
btVector3 m_origin;
};
@@ -191,6 +226,7 @@ btTransform::operator*(const btTransform& t) const
(*this)(t.m_origin));
}
+/**@brief Test if two transforms have all elements equal */
SIMD_FORCE_INLINE bool operator==(const btTransform& t1, const btTransform& t2)
{
return ( t1.getBasis() == t2.getBasis() &&
diff --git a/extern/bullet2/src/LinearMath/btTransformUtil.h b/extern/bullet2/src/LinearMath/btTransformUtil.h
index 86ee1da5edf..e8328da4ca6 100644
--- a/extern/bullet2/src/LinearMath/btTransformUtil.h
+++ b/extern/bullet2/src/LinearMath/btTransformUtil.h
@@ -100,6 +100,38 @@ public:
predictedTransform.setRotation(predictedOrn);
}
+ static void calculateVelocityQuaternion(const btVector3& pos0,const btVector3& pos1,const btQuaternion& orn0,const btQuaternion& orn1,btScalar timeStep,btVector3& linVel,btVector3& angVel)
+ {
+ linVel = (pos1 - pos0) / timeStep;
+ btVector3 axis;
+ btScalar angle;
+ if (orn0 != orn1)
+ {
+ calculateDiffAxisAngleQuaternion(orn0,orn1,axis,angle);
+ angVel = axis * angle / timeStep;
+ } else
+ {
+ angVel.setValue(0,0,0);
+ }
+ }
+
+ static void calculateDiffAxisAngleQuaternion(const btQuaternion& orn0,const btQuaternion& orn1a,btVector3& axis,btScalar& angle)
+ {
+ btQuaternion orn1 = orn0.farthest(orn1a);
+ btQuaternion dorn = orn1 * orn0.inverse();
+ ///floating point inaccuracy can lead to w component > 1..., which breaks
+ dorn.normalize();
+ angle = dorn.getAngle();
+ axis = btVector3(dorn.x(),dorn.y(),dorn.z());
+ axis[3] = btScalar(0.);
+ //check for axis length
+ btScalar len = axis.length2();
+ if (len < SIMD_EPSILON*SIMD_EPSILON)
+ axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));
+ else
+ axis /= btSqrt(len);
+ }
+
static void calculateVelocity(const btTransform& transform0,const btTransform& transform1,btScalar timeStep,btVector3& linVel,btVector3& angVel)
{
linVel = (transform1.getOrigin() - transform0.getOrigin()) / timeStep;
@@ -111,20 +143,11 @@ public:
static void calculateDiffAxisAngle(const btTransform& transform0,const btTransform& transform1,btVector3& axis,btScalar& angle)
{
-
- #ifdef USE_QUATERNION_DIFF
- btQuaternion orn0 = transform0.getRotation();
- btQuaternion orn1a = transform1.getRotation();
- btQuaternion orn1 = orn0.farthest(orn1a);
- btQuaternion dorn = orn1 * orn0.inverse();
-#else
btMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse();
btQuaternion dorn;
dmat.getRotation(dorn);
-#endif//USE_QUATERNION_DIFF
-
- ///floating point inaccuracy can lead to w component > 1..., which breaks
+ ///floating point inaccuracy can lead to w component > 1..., which breaks
dorn.normalize();
angle = dorn.getAngle();
@@ -140,5 +163,85 @@ public:
};
+
+///The btConvexSeparatingDistanceUtil can help speed up convex collision detection
+///by conservatively updating a cached separating distance/vector instead of re-calculating the closest distance
+class btConvexSeparatingDistanceUtil
+{
+ btQuaternion m_ornA;
+ btQuaternion m_ornB;
+ btVector3 m_posA;
+ btVector3 m_posB;
+
+ btVector3 m_separatingNormal;
+
+ btScalar m_boundingRadiusA;
+ btScalar m_boundingRadiusB;
+ btScalar m_separatingDistance;
+
+public:
+
+ btConvexSeparatingDistanceUtil(btScalar boundingRadiusA,btScalar boundingRadiusB)
+ :m_boundingRadiusA(boundingRadiusA),
+ m_boundingRadiusB(boundingRadiusB),
+ m_separatingDistance(0.f)
+ {
+ }
+
+ btScalar getConservativeSeparatingDistance()
+ {
+ return m_separatingDistance;
+ }
+
+ void updateSeparatingDistance(const btTransform& transA,const btTransform& transB)
+ {
+ const btVector3& toPosA = transA.getOrigin();
+ const btVector3& toPosB = transB.getOrigin();
+ btQuaternion toOrnA = transA.getRotation();
+ btQuaternion toOrnB = transB.getRotation();
+
+ if (m_separatingDistance>0.f)
+ {
+
+
+ btVector3 linVelA,angVelA,linVelB,angVelB;
+ btTransformUtil::calculateVelocityQuaternion(m_posA,toPosA,m_ornA,toOrnA,btScalar(1.),linVelA,angVelA);
+ btTransformUtil::calculateVelocityQuaternion(m_posB,toPosB,m_ornB,toOrnB,btScalar(1.),linVelB,angVelB);
+ btScalar maxAngularProjectedVelocity = angVelA.length() * m_boundingRadiusA + angVelB.length() * m_boundingRadiusB;
+ btVector3 relLinVel = (linVelB-linVelA);
+ btScalar relLinVelocLength = (linVelB-linVelA).dot(m_separatingNormal);
+ if (relLinVelocLength<0.f)
+ {
+ relLinVelocLength = 0.f;
+ }
+
+ btScalar projectedMotion = maxAngularProjectedVelocity +relLinVelocLength;
+ m_separatingDistance -= projectedMotion;
+ }
+
+ m_posA = toPosA;
+ m_posB = toPosB;
+ m_ornA = toOrnA;
+ m_ornB = toOrnB;
+ }
+
+ void initSeparatingDistance(const btVector3& separatingVector,btScalar separatingDistance,const btTransform& transA,const btTransform& transB)
+ {
+ m_separatingNormal = separatingVector;
+ m_separatingDistance = separatingDistance;
+
+ const btVector3& toPosA = transA.getOrigin();
+ const btVector3& toPosB = transB.getOrigin();
+ btQuaternion toOrnA = transA.getRotation();
+ btQuaternion toOrnB = transB.getRotation();
+ m_posA = toPosA;
+ m_posB = toPosB;
+ m_ornA = toOrnA;
+ m_ornB = toOrnB;
+ }
+
+};
+
+
#endif //SIMD_TRANSFORM_UTIL_H
diff --git a/extern/bullet2/src/LinearMath/btVector3.h b/extern/bullet2/src/LinearMath/btVector3.h
index 96548c6ba60..5d5c39e8587 100644
--- a/extern/bullet2/src/LinearMath/btVector3.h
+++ b/extern/bullet2/src/LinearMath/btVector3.h
@@ -17,127 +17,190 @@ subject to the following restrictions:
#ifndef SIMD__VECTOR3_H
#define SIMD__VECTOR3_H
-#include "btQuadWord.h"
-///btVector3 can be used to represent 3D points and vectors.
-///It has an un-used w component to suit 16-byte alignment when btVector3 is stored in containers. This extra component can be used by derived classes (Quaternion?) or by user
-///Ideally, this class should be replaced by a platform optimized SIMD version that keeps the data in registers
-class btVector3 : public btQuadWord {
+#include "btScalar.h"
+#include "btScalar.h"
+#include "btMinMax.h"
+/**@brief btVector3 can be used to represent 3D points and vectors.
+ * It has an un-used w component to suit 16-byte alignment when btVector3 is stored in containers. This extra component can be used by derived classes (Quaternion?) or by user
+ * Ideally, this class should be replaced by a platform optimized SIMD version that keeps the data in registers
+ */
+ATTRIBUTE_ALIGNED16(class) btVector3
+{
public:
- SIMD_FORCE_INLINE btVector3() {}
- SIMD_FORCE_INLINE btVector3(const btQuadWordStorage& q)
- : btQuadWord(q)
+#if defined (__SPU__) && defined (__CELLOS_LV2__)
+ union {
+ vec_float4 mVec128;
+ btScalar m_floats[4];
+ };
+public:
+ vec_float4 get128() const
{
+ return mVec128;
}
-
-
- SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z)
- :btQuadWord(x,y,z,btScalar(0.))
+public:
+#else //__CELLOS_LV2__ __SPU__
+#ifdef BT_USE_SSE // WIN32
+ union {
+ __m128 mVec128;
+ btScalar m_floats[4];
+ };
+ SIMD_FORCE_INLINE __m128 get128() const
{
+ return mVec128;
}
+ SIMD_FORCE_INLINE void set128(__m128 v128)
+ {
+ mVec128 = v128;
+ }
+#else
+ btScalar m_floats[4];
+#endif
+#endif //__CELLOS_LV2__ __SPU__
+
+ public:
-// SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
-// : btQuadWord(x,y,z,w)
-// {
-// }
+ /**@brief No initialization constructor */
+ SIMD_FORCE_INLINE btVector3() {}
+
+ /**@brief Constructor from scalars
+ * @param x X value
+ * @param y Y value
+ * @param z Z value
+ */
+ SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z)
+ {
+ m_floats[0] = x;
+ m_floats[1] = y;
+ m_floats[2] = z;
+ m_floats[3] = btScalar(0.);
+ }
+
+/**@brief Add a vector to this one
+ * @param The vector to add to this one */
SIMD_FORCE_INLINE btVector3& operator+=(const btVector3& v)
{
- m_x += v.x(); m_y += v.y(); m_z += v.z();
+ m_floats[0] += v.m_floats[0]; m_floats[1] += v.m_floats[1];m_floats[2] += v.m_floats[2];
return *this;
}
-
+ /**@brief Subtract a vector from this one
+ * @param The vector to subtract */
SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v)
{
- m_x -= v.x(); m_y -= v.y(); m_z -= v.z();
+ m_floats[0] -= v.m_floats[0]; m_floats[1] -= v.m_floats[1];m_floats[2] -= v.m_floats[2];
return *this;
}
-
+ /**@brief Scale the vector
+ * @param s Scale factor */
SIMD_FORCE_INLINE btVector3& operator*=(const btScalar& s)
{
- m_x *= s; m_y *= s; m_z *= s;
+ m_floats[0] *= s; m_floats[1] *= s;m_floats[2] *= s;
return *this;
}
+ /**@brief Inversely scale the vector
+ * @param s Scale factor to divide by */
SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s)
{
btFullAssert(s != btScalar(0.0));
return *this *= btScalar(1.0) / s;
}
+ /**@brief Return the dot product
+ * @param v The other vector in the dot product */
SIMD_FORCE_INLINE btScalar dot(const btVector3& v) const
{
- return m_x * v.x() + m_y * v.y() + m_z * v.z();
+ return m_floats[0] * v.m_floats[0] + m_floats[1] * v.m_floats[1] +m_floats[2] * v.m_floats[2];
}
+ /**@brief Return the length of the vector squared */
SIMD_FORCE_INLINE btScalar length2() const
{
return dot(*this);
}
+ /**@brief Return the length of the vector */
SIMD_FORCE_INLINE btScalar length() const
{
return btSqrt(length2());
}
+ /**@brief Return the distance squared between the ends of this and another vector
+ * This is symantically treating the vector like a point */
SIMD_FORCE_INLINE btScalar distance2(const btVector3& v) const;
+ /**@brief Return the distance between the ends of this and another vector
+ * This is symantically treating the vector like a point */
SIMD_FORCE_INLINE btScalar distance(const btVector3& v) const;
+ /**@brief Normalize this vector
+ * x^2 + y^2 + z^2 = 1 */
SIMD_FORCE_INLINE btVector3& normalize()
{
return *this /= length();
}
+ /**@brief Return a normalized version of this vector */
SIMD_FORCE_INLINE btVector3 normalized() const;
+ /**@brief Rotate this vector
+ * @param wAxis The axis to rotate about
+ * @param angle The angle to rotate by */
SIMD_FORCE_INLINE btVector3 rotate( const btVector3& wAxis, const btScalar angle );
+ /**@brief Return the angle between this and another vector
+ * @param v The other vector */
SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const
{
btScalar s = btSqrt(length2() * v.length2());
btFullAssert(s != btScalar(0.0));
return btAcos(dot(v) / s);
}
-
+ /**@brief Return a vector will the absolute values of each element */
SIMD_FORCE_INLINE btVector3 absolute() const
{
return btVector3(
- btFabs(m_x),
- btFabs(m_y),
- btFabs(m_z));
+ btFabs(m_floats[0]),
+ btFabs(m_floats[1]),
+ btFabs(m_floats[2]));
}
-
+ /**@brief Return the cross product between this and another vector
+ * @param v The other vector */
SIMD_FORCE_INLINE btVector3 cross(const btVector3& v) const
{
return btVector3(
- m_y * v.z() - m_z * v.y(),
- m_z * v.x() - m_x * v.z(),
- m_x * v.y() - m_y * v.x());
+ m_floats[1] * v.m_floats[2] -m_floats[2] * v.m_floats[1],
+ m_floats[2] * v.m_floats[0] - m_floats[0] * v.m_floats[2],
+ m_floats[0] * v.m_floats[1] - m_floats[1] * v.m_floats[0]);
}
SIMD_FORCE_INLINE btScalar triple(const btVector3& v1, const btVector3& v2) const
{
- return m_x * (v1.y() * v2.z() - v1.z() * v2.y()) +
- m_y * (v1.z() * v2.x() - v1.x() * v2.z()) +
- m_z * (v1.x() * v2.y() - v1.y() * v2.x());
+ return m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) +
+ m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) +
+ m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]);
}
+ /**@brief Return the axis with the smallest value
+ * Note return values are 0,1,2 for x, y, or z */
SIMD_FORCE_INLINE int minAxis() const
{
- return m_x < m_y ? (m_x < m_z ? 0 : 2) : (m_y < m_z ? 1 : 2);
+ return m_floats[0] < m_floats[1] ? (m_floats[0] <m_floats[2] ? 0 : 2) : (m_floats[1] <m_floats[2] ? 1 : 2);
}
+ /**@brief Return the axis with the largest value
+ * Note return values are 0,1,2 for x, y, or z */
SIMD_FORCE_INLINE int maxAxis() const
{
- return m_x < m_y ? (m_y < m_z ? 2 : 1) : (m_x < m_z ? 2 : 0);
+ return m_floats[0] < m_floats[1] ? (m_floats[1] <m_floats[2] ? 2 : 1) : (m_floats[0] <m_floats[2] ? 2 : 0);
}
SIMD_FORCE_INLINE int furthestAxis() const
@@ -153,67 +216,150 @@ public:
SIMD_FORCE_INLINE void setInterpolate3(const btVector3& v0, const btVector3& v1, btScalar rt)
{
btScalar s = btScalar(1.0) - rt;
- m_x = s * v0.x() + rt * v1.x();
- m_y = s * v0.y() + rt * v1.y();
- m_z = s * v0.z() + rt * v1.z();
+ m_floats[0] = s * v0.m_floats[0] + rt * v1.m_floats[0];
+ m_floats[1] = s * v0.m_floats[1] + rt * v1.m_floats[1];
+ m_floats[2] = s * v0.m_floats[2] + rt * v1.m_floats[2];
//don't do the unused w component
// m_co[3] = s * v0[3] + rt * v1[3];
}
+ /**@brief Return the linear interpolation between this and another vector
+ * @param v The other vector
+ * @param t The ration of this to v (t = 0 => return this, t=1 => return other) */
SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const
{
- return btVector3(m_x + (v.x() - m_x) * t,
- m_y + (v.y() - m_y) * t,
- m_z + (v.z() - m_z) * t);
+ return btVector3(m_floats[0] + (v.m_floats[0] - m_floats[0]) * t,
+ m_floats[1] + (v.m_floats[1] - m_floats[1]) * t,
+ m_floats[2] + (v.m_floats[2] -m_floats[2]) * t);
}
-
+ /**@brief Elementwise multiply this vector by the other
+ * @param v The other vector */
SIMD_FORCE_INLINE btVector3& operator*=(const btVector3& v)
{
- m_x *= v.x(); m_y *= v.y(); m_z *= v.z();
+ m_floats[0] *= v.m_floats[0]; m_floats[1] *= v.m_floats[1];m_floats[2] *= v.m_floats[2];
return *this;
}
-
+ /**@brief Return the x value */
+ SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; }
+ /**@brief Return the y value */
+ SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; }
+ /**@brief Return the z value */
+ SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; }
+ /**@brief Set the x value */
+ SIMD_FORCE_INLINE void setX(btScalar x) { m_floats[0] = x;};
+ /**@brief Set the y value */
+ SIMD_FORCE_INLINE void setY(btScalar y) { m_floats[1] = y;};
+ /**@brief Set the z value */
+ SIMD_FORCE_INLINE void setZ(btScalar z) {m_floats[2] = z;};
+ /**@brief Set the w value */
+ SIMD_FORCE_INLINE void setW(btScalar w) { m_floats[3] = w;};
+ /**@brief Return the x value */
+ SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; }
+ /**@brief Return the y value */
+ SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; }
+ /**@brief Return the z value */
+ SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; }
+ /**@brief Return the w value */
+ SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; }
+
+ //SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; }
+ //SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; }
+ ///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons.
+ SIMD_FORCE_INLINE operator btScalar *() { return &m_floats[0]; }
+ SIMD_FORCE_INLINE operator const btScalar *() const { return &m_floats[0]; }
+
+ SIMD_FORCE_INLINE bool operator==(const btVector3& other) const
+ {
+ return ((m_floats[3]==other.m_floats[3]) && (m_floats[2]==other.m_floats[2]) && (m_floats[1]==other.m_floats[1]) && (m_floats[0]==other.m_floats[0]));
+ }
+
+ SIMD_FORCE_INLINE bool operator!=(const btVector3& other) const
+ {
+ return !(*this == other);
+ }
+
+ /**@brief Set each element to the max of the current values and the values of another btVector3
+ * @param other The other btVector3 to compare with
+ */
+ SIMD_FORCE_INLINE void setMax(const btVector3& other)
+ {
+ btSetMax(m_floats[0], other.m_floats[0]);
+ btSetMax(m_floats[1], other.m_floats[1]);
+ btSetMax(m_floats[2], other.m_floats[2]);
+ btSetMax(m_floats[3], other.w());
+ }
+ /**@brief Set each element to the min of the current values and the values of another btVector3
+ * @param other The other btVector3 to compare with
+ */
+ SIMD_FORCE_INLINE void setMin(const btVector3& other)
+ {
+ btSetMin(m_floats[0], other.m_floats[0]);
+ btSetMin(m_floats[1], other.m_floats[1]);
+ btSetMin(m_floats[2], other.m_floats[2]);
+ btSetMin(m_floats[3], other.w());
+ }
+
+ SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z)
+ {
+ m_floats[0]=x;
+ m_floats[1]=y;
+ m_floats[2]=z;
+ m_floats[3] = 0.f;
+ }
+
+ void getSkewSymmetricMatrix(btVector3* v0,btVector3* v1,btVector3* v2) const
+ {
+ v0->setValue(0. ,-z() ,y());
+ v1->setValue(z() ,0. ,-x());
+ v2->setValue(-y() ,x() ,0.);
+ }
};
+/**@brief Return the sum of two vectors (Point symantics)*/
SIMD_FORCE_INLINE btVector3
operator+(const btVector3& v1, const btVector3& v2)
{
- return btVector3(v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z());
+ return btVector3(v1.m_floats[0] + v2.m_floats[0], v1.m_floats[1] + v2.m_floats[1], v1.m_floats[2] + v2.m_floats[2]);
}
+/**@brief Return the elementwise product of two vectors */
SIMD_FORCE_INLINE btVector3
operator*(const btVector3& v1, const btVector3& v2)
{
- return btVector3(v1.x() * v2.x(), v1.y() * v2.y(), v1.z() * v2.z());
+ return btVector3(v1.m_floats[0] * v2.m_floats[0], v1.m_floats[1] * v2.m_floats[1], v1.m_floats[2] * v2.m_floats[2]);
}
+/**@brief Return the difference between two vectors */
SIMD_FORCE_INLINE btVector3
operator-(const btVector3& v1, const btVector3& v2)
{
- return btVector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z());
+ return btVector3(v1.m_floats[0] - v2.m_floats[0], v1.m_floats[1] - v2.m_floats[1], v1.m_floats[2] - v2.m_floats[2]);
}
-
+/**@brief Return the negative of the vector */
SIMD_FORCE_INLINE btVector3
operator-(const btVector3& v)
{
- return btVector3(-v.x(), -v.y(), -v.z());
+ return btVector3(-v.m_floats[0], -v.m_floats[1], -v.m_floats[2]);
}
+/**@brief Return the vector scaled by s */
SIMD_FORCE_INLINE btVector3
operator*(const btVector3& v, const btScalar& s)
{
- return btVector3(v.x() * s, v.y() * s, v.z() * s);
+ return btVector3(v.m_floats[0] * s, v.m_floats[1] * s, v.m_floats[2] * s);
}
+/**@brief Return the vector scaled by s */
SIMD_FORCE_INLINE btVector3
operator*(const btScalar& s, const btVector3& v)
{
return v * s;
}
+/**@brief Return the vector inversely scaled by s */
SIMD_FORCE_INLINE btVector3
operator/(const btVector3& v, const btScalar& s)
{
@@ -221,12 +367,14 @@ operator/(const btVector3& v, const btScalar& s)
return v * (btScalar(1.0) / s);
}
+/**@brief Return the vector inversely scaled by s */
SIMD_FORCE_INLINE btVector3
operator/(const btVector3& v1, const btVector3& v2)
{
- return btVector3(v1.x() / v2.x(),v1.y() / v2.y(),v1.z() / v2.z());
+ return btVector3(v1.m_floats[0] / v2.m_floats[0],v1.m_floats[1] / v2.m_floats[1],v1.m_floats[2] / v2.m_floats[2]);
}
+/**@brief Return the dot product between two vectors */
SIMD_FORCE_INLINE btScalar
dot(const btVector3& v1, const btVector3& v2)
{
@@ -234,7 +382,7 @@ dot(const btVector3& v1, const btVector3& v2)
}
-
+/**@brief Return the distance squared between two vectors */
SIMD_FORCE_INLINE btScalar
distance2(const btVector3& v1, const btVector3& v2)
{
@@ -242,18 +390,21 @@ distance2(const btVector3& v1, const btVector3& v2)
}
+/**@brief Return the distance between two vectors */
SIMD_FORCE_INLINE btScalar
distance(const btVector3& v1, const btVector3& v2)
{
return v1.distance(v2);
}
+/**@brief Return the angle between two vectors */
SIMD_FORCE_INLINE btScalar
angle(const btVector3& v1, const btVector3& v2)
{
return v1.angle(v2);
}
+/**@brief Return the cross product of two vectors */
SIMD_FORCE_INLINE btVector3
cross(const btVector3& v1, const btVector3& v2)
{
@@ -266,6 +417,10 @@ triple(const btVector3& v1, const btVector3& v2, const btVector3& v3)
return v1.triple(v2, v3);
}
+/**@brief Return the linear interpolation between two vectors
+ * @param v1 One vector
+ * @param v2 The other vector
+ * @param t The ration of this to v (t = 0 => return v1, t=1 => return v2) */
SIMD_FORCE_INLINE btVector3
lerp(const btVector3& v1, const btVector3& v2, const btScalar& t)
{
@@ -273,10 +428,6 @@ lerp(const btVector3& v1, const btVector3& v2, const btScalar& t)
}
-SIMD_FORCE_INLINE bool operator==(const btVector3& p1, const btVector3& p2)
-{
- return p1.x() == p2.x() && p1.y() == p2.y() && p1.z() == p2.z();
-}
SIMD_FORCE_INLINE btScalar btVector3::distance2(const btVector3& v) const
{
@@ -316,47 +467,47 @@ public:
SIMD_FORCE_INLINE btVector4(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
: btVector3(x,y,z)
{
- m_unusedW = w;
+ m_floats[3] = w;
}
SIMD_FORCE_INLINE btVector4 absolute4() const
{
return btVector4(
- btFabs(m_x),
- btFabs(m_y),
- btFabs(m_z),
- btFabs(m_unusedW));
+ btFabs(m_floats[0]),
+ btFabs(m_floats[1]),
+ btFabs(m_floats[2]),
+ btFabs(m_floats[3]));
}
- btScalar getW() const { return m_unusedW;}
+ btScalar getW() const { return m_floats[3];}
SIMD_FORCE_INLINE int maxAxis4() const
{
int maxIndex = -1;
btScalar maxVal = btScalar(-1e30);
- if (m_x > maxVal)
+ if (m_floats[0] > maxVal)
{
maxIndex = 0;
- maxVal = m_x;
+ maxVal = m_floats[0];
}
- if (m_y > maxVal)
+ if (m_floats[1] > maxVal)
{
maxIndex = 1;
- maxVal = m_y;
+ maxVal = m_floats[1];
}
- if (m_z > maxVal)
+ if (m_floats[2] > maxVal)
{
maxIndex = 2;
- maxVal = m_z;
+ maxVal =m_floats[2];
}
- if (m_unusedW > maxVal)
+ if (m_floats[3] > maxVal)
{
maxIndex = 3;
- maxVal = m_unusedW;
+ maxVal = m_floats[3];
}
@@ -371,25 +522,25 @@ public:
{
int minIndex = -1;
btScalar minVal = btScalar(1e30);
- if (m_x < minVal)
+ if (m_floats[0] < minVal)
{
minIndex = 0;
- minVal = m_x;
+ minVal = m_floats[0];
}
- if (m_y < minVal)
+ if (m_floats[1] < minVal)
{
minIndex = 1;
- minVal = m_y;
+ minVal = m_floats[1];
}
- if (m_z < minVal)
+ if (m_floats[2] < minVal)
{
minIndex = 2;
- minVal = m_z;
+ minVal =m_floats[2];
}
- if (m_unusedW < minVal)
+ if (m_floats[3] < minVal)
{
minIndex = 3;
- minVal = m_unusedW;
+ minVal = m_floats[3];
}
return minIndex;
@@ -402,6 +553,40 @@ public:
return absolute4().maxAxis4();
}
+
+
+
+ /**@brief Set x,y,z and zero w
+ * @param x Value of x
+ * @param y Value of y
+ * @param z Value of z
+ */
+
+
+/* void getValue(btScalar *m) const
+ {
+ m[0] = m_floats[0];
+ m[1] = m_floats[1];
+ m[2] =m_floats[2];
+ }
+*/
+/**@brief Set the values
+ * @param x Value of x
+ * @param y Value of y
+ * @param z Value of z
+ * @param w Value of w
+ */
+ SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
+ {
+ m_floats[0]=x;
+ m_floats[1]=y;
+ m_floats[2]=z;
+ m_floats[3]=w;
+ }
+
+
+
+
};
diff --git a/extern/bullet2/src/SConscript b/extern/bullet2/src/SConscript
index 5811e97319d..bd7fb87b01f 100644
--- a/extern/bullet2/src/SConscript
+++ b/extern/bullet2/src/SConscript
@@ -10,7 +10,7 @@ cflags = []
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
defs += ' WIN32 NDEBUG _WINDOWS _LIB'
#cflags += ['/MT', '/W3', '/GX', '/O2', '/Op']
- cflags += ['/MT', '/W3', '/GX', '/Og', '/Ot', '/Ob1', '/Op', '/G6']
+ cflags += ['/MT', '/W3', '/GX', '/Og', '/Ot', '/Ob1', '/Op', '/G6', '/O3']
elif env['OURPLATFORM']=='win32-mingw':
defs += ' NDEBUG'
cflags += ['-O2']
diff --git a/extern/libopenjpeg/CMakeLists.txt b/extern/libopenjpeg/CMakeLists.txt
new file mode 100644
index 00000000000..c179d5328b9
--- /dev/null
+++ b/extern/libopenjpeg/CMakeLists.txt
@@ -0,0 +1,32 @@
+# $Id: CMakeLists.txt 14444 2008-04-16 22:40:48Z hos $
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Jacques Beaurain.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+SET(INC . src ${FREETYPE_INC})
+
+FILE(GLOB SRC *.c except t1_generate_luts.c)
+ADD_DEFINITIONS(-DWITH_OPENJPEG)
+BLENDERLIB(extern_libopenjpeg "${SRC}" "${INC}")
+#, libtype=['international','player'], priority=[5, 210])
diff --git a/extern/libopenjpeg/Makefile b/extern/libopenjpeg/Makefile
new file mode 100644
index 00000000000..15d9d9c7c01
--- /dev/null
+++ b/extern/libopenjpeg/Makefile
@@ -0,0 +1,43 @@
+#
+# $Id: Makefile 14444 2008-04-16 22:40:48Z hos $
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+#
+
+LIBNAME = openjpeg
+DIR = $(OCGDIR)/extern/$(LIBNAME)
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+TCSRCS = $(wildcard *.c)
+CSRCS = $(filter-out t1_generate_luts.c,$(TCSRCS))
+
+include nan_compile.mk
+CPPFLAGS += -I.
+
+install: all debug
+
diff --git a/extern/libopenjpeg/SConscript b/extern/libopenjpeg/SConscript
index 14b7102cbcd..13a34bf5598 100644
--- a/extern/libopenjpeg/SConscript
+++ b/extern/libopenjpeg/SConscript
@@ -5,6 +5,7 @@ import sys
Import('env')
sources = env.Glob('*.c')
+
incs = '.'
flags = []
defs = []
diff --git a/extern/libopenjpeg/t1_generate_luts.c b/extern/libopenjpeg/t1_generate_luts.c
deleted file mode 100644
index 1925b951f1b..00000000000
--- a/extern/libopenjpeg/t1_generate_luts.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
- * Copyright (c) 2002-2007, Professor Benoit Macq
- * Copyright (c) 2001-2003, David Janssens
- * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
- * Copyright (c) 2005, Herve Drolon, FreeImage Team
- * Copyright (c) 2007, Callum Lerwick <seg@haxxed.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "opj_includes.h"
-#include <math.h>
-
-static int t1_init_ctxno_zc(int f, int orient) {
- int h, v, d, n, t, hv;
- n = 0;
- h = ((f & T1_SIG_W) != 0) + ((f & T1_SIG_E) != 0);
- v = ((f & T1_SIG_N) != 0) + ((f & T1_SIG_S) != 0);
- d = ((f & T1_SIG_NW) != 0) + ((f & T1_SIG_NE) != 0) + ((f & T1_SIG_SE) != 0) + ((f & T1_SIG_SW) != 0);
-
- switch (orient) {
- case 2:
- t = h;
- h = v;
- v = t;
- case 0:
- case 1:
- if (!h) {
- if (!v) {
- if (!d)
- n = 0;
- else if (d == 1)
- n = 1;
- else
- n = 2;
- } else if (v == 1) {
- n = 3;
- } else {
- n = 4;
- }
- } else if (h == 1) {
- if (!v) {
- if (!d)
- n = 5;
- else
- n = 6;
- } else {
- n = 7;
- }
- } else
- n = 8;
- break;
- case 3:
- hv = h + v;
- if (!d) {
- if (!hv) {
- n = 0;
- } else if (hv == 1) {
- n = 1;
- } else {
- n = 2;
- }
- } else if (d == 1) {
- if (!hv) {
- n = 3;
- } else if (hv == 1) {
- n = 4;
- } else {
- n = 5;
- }
- } else if (d == 2) {
- if (!hv) {
- n = 6;
- } else {
- n = 7;
- }
- } else {
- n = 8;
- }
- break;
- }
-
- return (T1_CTXNO_ZC + n);
-}
-
-static int t1_init_ctxno_sc(int f) {
- int hc, vc, n;
- n = 0;
-
- hc = int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
- T1_SIG_E) + ((f & (T1_SIG_W | T1_SGN_W)) == T1_SIG_W),
- 1) - int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
- (T1_SIG_E | T1_SGN_E)) +
- ((f & (T1_SIG_W | T1_SGN_W)) ==
- (T1_SIG_W | T1_SGN_W)), 1);
-
- vc = int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
- T1_SIG_N) + ((f & (T1_SIG_S | T1_SGN_S)) == T1_SIG_S),
- 1) - int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
- (T1_SIG_N | T1_SGN_N)) +
- ((f & (T1_SIG_S | T1_SGN_S)) ==
- (T1_SIG_S | T1_SGN_S)), 1);
-
- if (hc < 0) {
- hc = -hc;
- vc = -vc;
- }
- if (!hc) {
- if (vc == -1)
- n = 1;
- else if (!vc)
- n = 0;
- else
- n = 1;
- } else if (hc == 1) {
- if (vc == -1)
- n = 2;
- else if (!vc)
- n = 3;
- else
- n = 4;
- }
-
- return (T1_CTXNO_SC + n);
-}
-
-static int t1_init_spb(int f) {
- int hc, vc, n;
-
- hc = int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
- T1_SIG_E) + ((f & (T1_SIG_W | T1_SGN_W)) == T1_SIG_W),
- 1) - int_min(((f & (T1_SIG_E | T1_SGN_E)) ==
- (T1_SIG_E | T1_SGN_E)) +
- ((f & (T1_SIG_W | T1_SGN_W)) ==
- (T1_SIG_W | T1_SGN_W)), 1);
-
- vc = int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
- T1_SIG_N) + ((f & (T1_SIG_S | T1_SGN_S)) == T1_SIG_S),
- 1) - int_min(((f & (T1_SIG_N | T1_SGN_N)) ==
- (T1_SIG_N | T1_SGN_N)) +
- ((f & (T1_SIG_S | T1_SGN_S)) ==
- (T1_SIG_S | T1_SGN_S)), 1);
-
- if (!hc && !vc)
- n = 0;
- else
- n = (!(hc > 0 || (!hc && vc > 0)));
-
- return n;
-}
-
-void dump_array16(int array[],int size){
- int i;
- --size;
- for (i = 0; i < size; ++i) {
- printf("0x%04x, ", array[i]);
- if(!((i+1)&0x7))
- printf("\n ");
- }
- printf("0x%04x\n};\n\n", array[size]);
-}
-
-int main(){
- int i, j;
- double u, v, t;
-
- int lut_ctxno_zc[1024];
- int lut_nmsedec_sig[1 << T1_NMSEDEC_BITS];
- int lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS];
- int lut_nmsedec_ref[1 << T1_NMSEDEC_BITS];
- int lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS];
-
- printf("/* This file was automatically generated by t1_generate_luts.c */\n\n");
-
- // lut_ctxno_zc
- for (j = 0; j < 4; ++j) {
- for (i = 0; i < 256; ++i) {
- int orient = j;
- if (orient == 2) {
- orient = 1;
- } else if (orient == 1) {
- orient = 2;
- }
- lut_ctxno_zc[(orient << 8) | i] = t1_init_ctxno_zc(i, j);
- }
- }
-
- printf("static char lut_ctxno_zc[1024] = {\n ");
- for (i = 0; i < 1023; ++i) {
- printf("%i, ", lut_ctxno_zc[i]);
- if(!((i+1)&0x1f))
- printf("\n ");
- }
- printf("%i\n};\n\n", lut_ctxno_zc[1023]);
-
- // lut_ctxno_sc
- printf("static char lut_ctxno_sc[256] = {\n ");
- for (i = 0; i < 255; ++i) {
- printf("0x%x, ", t1_init_ctxno_sc(i << 4));
- if(!((i+1)&0xf))
- printf("\n ");
- }
- printf("0x%x\n};\n\n", t1_init_ctxno_sc(255 << 4));
-
- // lut_spb
- printf("static char lut_spb[256] = {\n ");
- for (i = 0; i < 255; ++i) {
- printf("%i, ", t1_init_spb(i << 4));
- if(!((i+1)&0x1f))
- printf("\n ");
- }
- printf("%i\n};\n\n", t1_init_spb(255 << 4));
-
- /* FIXME FIXME FIXME */
- /* fprintf(stdout,"nmsedec luts:\n"); */
- for (i = 0; i < (1 << T1_NMSEDEC_BITS); ++i) {
- t = i / pow(2, T1_NMSEDEC_FRACBITS);
- u = t;
- v = t - 1.5;
- lut_nmsedec_sig[i] =
- int_max(0,
- (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
- lut_nmsedec_sig0[i] =
- int_max(0,
- (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
- u = t - 1.0;
- if (i & (1 << (T1_NMSEDEC_BITS - 1))) {
- v = t - 1.5;
- } else {
- v = t - 0.5;
- }
- lut_nmsedec_ref[i] =
- int_max(0,
- (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
- lut_nmsedec_ref0[i] =
- int_max(0,
- (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0));
- }
-
- printf("static short lut_nmsedec_sig[1 << T1_NMSEDEC_BITS] = {\n ");
- dump_array16(&lut_nmsedec_sig, 1 << T1_NMSEDEC_BITS);
-
- printf("static short lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS] = {\n ");
- dump_array16(&lut_nmsedec_sig0, 1 << T1_NMSEDEC_BITS);
-
- printf("static short lut_nmsedec_ref[1 << T1_NMSEDEC_BITS] = {\n ");
- dump_array16(&lut_nmsedec_ref, 1 << T1_NMSEDEC_BITS);
-
- printf("static short lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS] = {\n ");
- dump_array16(&lut_nmsedec_ref0, 1 << T1_NMSEDEC_BITS);
-
- return 0;
-}
diff --git a/extern/libredcode/codec.c b/extern/libredcode/codec.c
index e0b79119e80..f47a85cbb13 100644
--- a/extern/libredcode/codec.c
+++ b/extern/libredcode/codec.c
@@ -64,7 +64,7 @@ struct redcode_frame_raw * redcode_decode_video_raw(
/* setup the decoder decoding parameters using the current image
and user parameters */
opj_setup_decoder(dinfo, &parameters);
-
+
/* open a byte stream */
cio = opj_cio_open((opj_common_ptr)dinfo,
frame->data + frame->offset, frame->length);
diff --git a/extern/libredcode/format.c b/extern/libredcode/format.c
index 4677c49b8a5..cf8f9d5faa7 100644
--- a/extern/libredcode/format.c
+++ b/extern/libredcode/format.c
@@ -1,49 +1,50 @@
-#ifdef _WIN32
-#include <Winsock2.h>
-#else
-#include <netinet/in.h>
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "format.h"
struct red_reob {
- unsigned long len;
- char head[4];
+ unsigned int len;
+ unsigned int head;
- unsigned long rdvo;
- unsigned long rdvs;
- unsigned long rdao;
- unsigned long rdas;
+ unsigned int rdvo;
+ unsigned int rdvs;
+ unsigned int rdao;
+ unsigned int rdas;
- unsigned long unknown1;
- unsigned long unknown2;
- unsigned long totlen;
+ unsigned int unknown1;
+ unsigned int unknown2;
+ unsigned int totlen;
- unsigned long avgv;
- unsigned long avgs;
+ unsigned int avgv;
+ unsigned int avgs;
- unsigned long unknown3;
- unsigned long unknown4;
- unsigned long unknown5;
+ unsigned int unknown3;
+ unsigned int unknown4;
+ unsigned int unknown5;
};
struct redcode_handle {
FILE * fp;
struct red_reob * reob;
- unsigned long * rdvo;
- unsigned long * rdvs;
- unsigned long * rdao;
- unsigned long * rdas;
+ unsigned int * rdvo;
+ unsigned int * rdvs;
+ unsigned int * rdao;
+ unsigned int * rdas;
long cfra;
+ long length;
};
+unsigned int read_be32(unsigned int val)
+{
+ unsigned char * v = (unsigned char*) & val;
+
+ return (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3];
+}
static unsigned char* read_packet(FILE * fp, char * expect)
{
- unsigned long len;
+ unsigned int len;
char head[5];
unsigned char * rv;
@@ -52,7 +53,7 @@ static unsigned char* read_packet(FILE * fp, char * expect)
head[4] = 0;
- len = ntohl(len);
+ len = read_be32(len);
if (strcmp(expect, head) != 0) {
fprintf(stderr, "Read: %s, expect: %s\n", head, expect);
@@ -69,9 +70,9 @@ static unsigned char* read_packet(FILE * fp, char * expect)
return rv;
}
-static unsigned long * read_index_packet(FILE * fp, char * expect)
+static unsigned int * read_index_packet(FILE * fp, char * expect)
{
- unsigned long * rv = (unsigned long*) read_packet(fp, expect);
+ unsigned int * rv = (unsigned int*) read_packet(fp, expect);
int i;
if (!rv) {
@@ -79,7 +80,7 @@ static unsigned long * read_index_packet(FILE * fp, char * expect)
}
for (i = 2; i < rv[0]/4; i++) {
- rv[i] = ntohl(rv[i]);
+ rv[i] = read_be32(rv[i]);
}
return rv;
}
@@ -91,14 +92,14 @@ static struct red_reob * read_reob(FILE * fp)
return (struct red_reob *) read_index_packet(fp, "REOB");
}
-static unsigned long * read_index(FILE * fp, unsigned long i, char * expect)
+static unsigned int * read_index(FILE * fp, unsigned int i, char * expect)
{
fseek(fp, i, SEEK_SET);
- return (unsigned long*) read_index_packet(fp, expect);
+ return (unsigned int*) read_index_packet(fp, expect);
}
-static unsigned char * read_data(FILE * fp, unsigned long i, char * expect)
+static unsigned char * read_data(FILE * fp, unsigned int i, char * expect)
{
fseek(fp, i, SEEK_SET);
@@ -109,6 +110,7 @@ struct redcode_handle * redcode_open(const char * fname)
{
struct redcode_handle * rv = NULL;
struct red_reob * reob = NULL;
+ int i;
FILE * fp = fopen(fname, "rb");
@@ -136,6 +138,12 @@ struct redcode_handle * redcode_open(const char * fname)
return NULL;
}
+ for (i = 0; i < (rv->rdvo[0] - 8)/4; i++) {
+ if (rv->rdvo[i + 2]) {
+ rv->length = i;
+ }
+ }
+
return rv;
}
@@ -162,7 +170,7 @@ void redcode_close(struct redcode_handle * handle)
long redcode_get_length(struct redcode_handle * handle)
{
- return handle->rdvo[0]/4;
+ return handle->length;
}
struct redcode_frame * redcode_read_video_frame(
@@ -182,7 +190,7 @@ struct redcode_frame * redcode_read_video_frame(
rv = (struct redcode_frame*) calloc(1, sizeof(struct redcode_frame));
rv->offset = 12+8;
- rv->length = *(unsigned long*)data - rv->offset;
+ rv->length = *(unsigned int*)data - rv->offset;
rv->data = data;
return rv;
@@ -205,7 +213,7 @@ struct redcode_frame * redcode_read_audio_frame(
rv = (struct redcode_frame*) calloc(1, sizeof(struct redcode_frame));
rv->offset = 24+8;
- rv->length = *(unsigned long*)data - rv->offset;
+ rv->length = *(unsigned int*)data - rv->offset;
rv->data = data;
return rv;
diff --git a/extern/libredcode/format.h b/extern/libredcode/format.h
index e09ea8a3b64..b2c6b2d885b 100644
--- a/extern/libredcode/format.h
+++ b/extern/libredcode/format.h
@@ -3,8 +3,8 @@
struct redcode_handle;
struct redcode_frame {
- unsigned long length;
- unsigned long offset;
+ unsigned int length;
+ unsigned int offset;
unsigned char * data;
};
diff --git a/intern/SoundSystem/openal/SND_OpenALDevice.cpp b/intern/SoundSystem/openal/SND_OpenALDevice.cpp
index c660e9aecba..9ce30f985ac 100644
--- a/intern/SoundSystem/openal/SND_OpenALDevice.cpp
+++ b/intern/SoundSystem/openal/SND_OpenALDevice.cpp
@@ -235,7 +235,8 @@ SND_OpenALDevice::SND_OpenALDevice()
if (m_context) {
#ifdef AL_VERSION_1_1
- alcMakeContextCurrent((ALCcontext*)m_context);
+ alcMakeContextCurrent((ALCcontext*)m_context);
+ alutInitWithoutContext(NULL, NULL); /* in this case we dont want alut to initialize the context, see above */
#else
alcMakeContextCurrent(m_context);
#endif
@@ -380,6 +381,9 @@ SND_OpenALDevice::~SND_OpenALDevice()
#else
if (m_device)
alcCloseDevice((ALCdevice*) m_device);
+#ifdef AL_VERSION_1_1
+ alutExit();
+#endif
#endif
}
@@ -437,7 +441,9 @@ SND_WaveSlot* SND_OpenALDevice::LoadSample(const STR_String& name,
alutLoadWAVMemory((char*)memlocation, &sampleformat, &data, &numberofsamples, &samplerate); // openal_2.12
#else
#ifdef AL_VERSION_1_1
- alutLoadWAVMemory((ALbyte*)memlocation, &sampleformat, &data, &numberofsamples, &samplerate, &loop);// openal_2.14+
+ float frequency = 0.0f;
+ data = alutLoadMemoryFromFileImage(memlocation, size, &sampleformat, &numberofsamples, &frequency);
+ samplerate = (int)frequency;
#else
alutLoadWAVMemory((signed char*)memlocation, &sampleformat, &data, &numberofsamples, &samplerate, &loop);// openal_2.14+
@@ -480,7 +486,11 @@ SND_WaveSlot* SND_OpenALDevice::LoadSample(const STR_String& name,
}
/* and free the original stuff (copy was made in openal) */
+#if defined(OUDE_OPENAL) || defined (__APPLE__) || !defined(AL_VERSION_1_1)
alutUnloadWAV(sampleformat, data, numberofsamples, samplerate);
+#else
+ free(data);
+#endif
}
}
else
diff --git a/intern/SoundSystem/openal/SND_OpenALDevice.h b/intern/SoundSystem/openal/SND_OpenALDevice.h
index b8c64762a56..a7b97cc314f 100644
--- a/intern/SoundSystem/openal/SND_OpenALDevice.h
+++ b/intern/SoundSystem/openal/SND_OpenALDevice.h
@@ -32,7 +32,7 @@
#include "SND_AudioDevice.h"
#include "SoundDefines.h"
-typedef struct SDL_CD;
+struct SDL_CD;
class SND_OpenALDevice : public SND_AudioDevice
{
diff --git a/intern/SoundSystem/sdl/SND_SDLCDDevice.h b/intern/SoundSystem/sdl/SND_SDLCDDevice.h
index 15cb1975d74..96600d53630 100644
--- a/intern/SoundSystem/sdl/SND_SDLCDDevice.h
+++ b/intern/SoundSystem/sdl/SND_SDLCDDevice.h
@@ -29,7 +29,7 @@
#ifndef SND_SDLCDDEVICE
#define SND_SDLCDDEVICE
-typedef struct SDL_CD;
+struct SDL_CD;
class SND_SDLCDDevice
{
diff --git a/intern/decimation/SConscript b/intern/decimation/SConscript
index 55de37f3c69..ef95a795928 100644
--- a/intern/decimation/SConscript
+++ b/intern/decimation/SConscript
@@ -5,4 +5,4 @@ sources = env.Glob('intern/*.cpp')
incs = '. ../moto/include ../container ../memutil'
-env.BlenderLib ('bf_decimation', sources, Split(incs) , [], libtype=['intern', 'player'], priority = [10, 20] )
+env.BlenderLib ('bf_decimation', sources, Split(incs) , [], libtype=['core'], priority = [10] )
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 2e76b50fe7a..c6ce7b628e9 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -1010,11 +1010,11 @@ getClipboard(bool selection
) const {
//Flag
//0 = Regular clipboard 1 = selection
- static Atom Primary_atom, clip_String, compound_text;
+ static Atom Primary_atom, clip_String, compound_text, a_text, a_string;
Atom rtype;
Window m_window, owner;
unsigned char *data, *tmp_data;
- int bits;
+ int bits, count;
unsigned long len, bytes;
XEvent xevent;
@@ -1025,6 +1025,8 @@ getClipboard(bool selection
clip_String = XInternAtom(m_display, "_BLENDER_STRING", False);
compound_text = XInternAtom(m_display, "COMPOUND_TEXT", False);
+ a_text= XInternAtom(m_display, "TEXT", False);
+ a_string= XInternAtom(m_display, "STRING", False);
//lets check the owner and if it is us then return the static buffer
if(!selection) {
@@ -1058,18 +1060,46 @@ getClipboard(bool selection
XFlush(m_display);
//This needs to change so we do not wait for ever or check owner first
+ count= 1;
while(1) {
XNextEvent(m_display, &xevent);
if(xevent.type == SelectionNotify) {
- if(XGetWindowProperty(m_display, m_window, xevent.xselection.property, 0L, 4096L, False, AnyPropertyType, &rtype, &bits, &len, &bytes, &data) == Success) {
- if (data) {
- tmp_data = (unsigned char*) malloc(strlen((char*)data)+1);
- strcpy((char*)tmp_data, (char*)data);
- XFree(data);
- return (GHOST_TUns8*)tmp_data;
+ if (xevent.xselection.property == None) {
+ /* Ok, the client can't convert the property
+ * to some that we can handle, try other types..
+ */
+ if (count == 1) {
+ XConvertSelection(m_display, Primary_atom, a_text, clip_String, m_window, CurrentTime);
+ count++;
+ }
+ else if (count == 2) {
+ XConvertSelection(m_display, Primary_atom, a_string, clip_String, m_window, CurrentTime);
+ count++;
+ }
+ else {
+ /* Ok, the owner of the selection can't
+ * convert the data to something that we can
+ * handle.
+ */
+ return(NULL);
}
}
- return NULL;
+ else {
+ if(XGetWindowProperty(m_display, m_window, xevent.xselection.property , 0L, 4096L, False, AnyPropertyType, &rtype, &bits, &len, &bytes, &data) == Success) {
+ if (data) {
+ if (bits == 8 && (rtype == compound_text || rtype == a_text || rtype == a_string)) {
+ tmp_data = (unsigned char*) malloc(strlen((char*)data)+1);
+ strcpy((char*)tmp_data, (char*)data);
+ }
+ else
+ tmp_data= NULL;
+
+ XFree(data);
+ return (GHOST_TUns8*)tmp_data;
+ }
+ }
+ return(NULL);
+ }
}
}
}
diff --git a/intern/opennl/SConscript b/intern/opennl/SConscript
index 8cd5f9c1548..f68810d2f16 100644
--- a/intern/opennl/SConscript
+++ b/intern/opennl/SConscript
@@ -6,7 +6,7 @@ sources = env.Glob('intern/*.c') + env.Glob('superlu/*.c')
incs = 'extern superlu'
if (env['OURPLATFORM'] == 'win32-mingw'):
- env.BlenderLib ('blender_ONL', sources, Split(incs), [], libtype=['intern','player'], priority=[80,22] )
+ env.BlenderLib ('blender_ONL', sources, Split(incs), [], libtype=['core','intern'], priority=[1,80] )
else:
- env.BlenderLib ('blender_ONL', sources, Split(incs), [], libtype=['intern','player'], priority=[65,22] )
+ env.BlenderLib ('blender_ONL', sources, Split(incs), [], libtype=['core'], priority=[55] )
diff --git a/intern/opennl/superlu/get_perm_c.c b/intern/opennl/superlu/get_perm_c.c
index e255b4a76bd..4c0ee95c4c6 100644
--- a/intern/opennl/superlu/get_perm_c.c
+++ b/intern/opennl/superlu/get_perm_c.c
@@ -366,6 +366,10 @@ get_perm_c(int ispec, SuperMatrix *A, int *perm_c)
int *b_rowind, *dhead, *qsize, *llist, *marker;
double t, SuperLU_timer_();
+ /* make gcc happy */
+ b_rowind=NULL;
+ b_colptr=NULL;
+
m = A->nrow;
n = A->ncol;
diff --git a/projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj b/projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj
index 90d0bd70d7a..69bce6b621b 100644
--- a/projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj
+++ b/projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj
@@ -553,6 +553,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\imbuf\intern\jp2.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\imbuf\intern\jpeg.c"
>
</File>
@@ -831,6 +835,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\imbuf\intern\IMB_jp2.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\imbuf\intern\IMB_jpeg.h"
>
</File>
diff --git a/projectfiles_vc9/blender/nodes/nodes.vcproj b/projectfiles_vc9/blender/nodes/nodes.vcproj
index 322b8e609d0..a289fffb3c2 100644
--- a/projectfiles_vc9/blender/nodes/nodes.vcproj
+++ b/projectfiles_vc9/blender/nodes/nodes.vcproj
@@ -617,6 +617,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_compose.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_coord.c"
>
</File>
@@ -625,6 +629,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_decompose.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_distance.c"
>
</File>
@@ -661,6 +669,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_scale.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_texture.c"
>
</File>
@@ -669,6 +681,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_valToNor.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\nodes\intern\TEX_nodes\TEX_valToRgb.c"
>
</File>
diff --git a/projectfiles_vc9/gameengine/blenderhook/KX_blenderhook.vcproj b/projectfiles_vc9/gameengine/blenderhook/KX_blenderhook.vcproj
index 64f6b92ef29..8e027fd1854 100644
--- a/projectfiles_vc9/gameengine/blenderhook/KX_blenderhook.vcproj
+++ b/projectfiles_vc9/gameengine/blenderhook/KX_blenderhook.vcproj
@@ -4,6 +4,7 @@
Version="9,00"
Name="KX_blenderhook"
ProjectGUID="{8154A59A-CAED-403D-AB94-BC4E7C032666}"
+ RootNamespace="KX_blenderhook"
TargetFrameworkVersion="131072"
>
<Platforms>
@@ -43,7 +44,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenloader;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\ketsji;..\..\..\source\gameengine\network;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Physics\Sumo;..\..\..\source\gameengine\Physics\common;..\..\..\source\gameengine\network\loopbacknetwork;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\Physics\Sumo\Fuzzics\include;..\..\..\source\blender\gpu"
- PreprocessorDefinitions="WIN32;_LIB;_DEBUG;WITH_GLEXT"
+ PreprocessorDefinitions="WIN32;_LIB;_DEBUG;WITH_GLEXT;WITH_FFMPEG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
DefaultCharIsUnsigned="true"
@@ -119,7 +120,7 @@
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\build\msvc_9\extern\solid\include;..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\lib\windows\python\include\python2.5;..\..\..\source\blender;..\..\..\source\blender\misc;..\..\..\source\blender\imbuf;..\..\..\source\blender\blenlib;..\..\..\source\blender\include;..\..\..\source\blender\makesdna;..\..\..\source\blender\blenloader;..\..\..\source\blender\blenkernel;..\..\..\source\kernel\gen_system;..\..\..\source\gameengine\ketsji;..\..\..\source\gameengine\network;..\..\..\source\gameengine\rasterizer;..\..\..\source\gameengine\Converter;..\..\..\source\gameengine\gamelogic;..\..\..\source\gameengine\scenegraph;..\..\..\source\gameengine\expressions;..\..\..\source\gameengine\Physics\Sumo;..\..\..\source\gameengine\Physics\common;..\..\..\source\gameengine\network\loopbacknetwork;..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\source\gameengine\Physics\Sumo\Fuzzics\include;..\..\..\source\blender\gpu"
- PreprocessorDefinitions="NDEBUG;WIN32;_LIB;USE_SUMO_SOLID;WITH_GLEXT"
+ PreprocessorDefinitions="NDEBUG;WIN32;_LIB;USE_SUMO_SOLID;WITH_GLEXT;WITH_FFMPEG"
StringPooling="true"
BasicRuntimeChecks="0"
RuntimeLibrary="0"
diff --git a/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj b/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj
index ab0b05c208c..fe20152388a 100644
--- a/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj
+++ b/projectfiles_vc9/gameengine/gameplayer/ghost/GP_ghost.vcproj
@@ -45,7 +45,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\intern\openal\include;..\..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\..\build\msvc_9\intern\SoundSystem\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\source\blender\include;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenloader;..\..\..\..\source\blender\readblenfile;..\..\..\..\source\blender\render\extern\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\kernel\gen_messaging;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Physics;..\..\..\..\source\gameengine\network;..\..\..\..\source\gameengine\rasterizer;..\..\..\..\source\gameengine\converter;..\..\..\..\source\gameengine\gamelogic;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\scenegraph;..\..\..\..\source\gameengine\Physics\Ode;..\..\..\..\source\gameengine\soundsystem;..\..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\..\source\gameengine\gameplayer\common;..\..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\source\gameengine\network\loopbacknetwork;..\..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\..\source\gameengine\gameplayer\common\windows;..\..\..\..\source\sumo\include;..\..\..\..\source\sumo\fuzzics\include;..\..\..\..\source\blender\gpu;..\..\..\..\..\build\msvc_9\intern\guardedalloc\include"
- PreprocessorDefinitions="WIN32,_CONSOLE,dSINGLE, _DEBUG"
+ PreprocessorDefinitions="WIN32,_CONSOLE,dSINGLE, _DEBUG;WITH_FFMPEG"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
@@ -72,7 +72,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386&#x0D;&#x0A;"
- AdditionalDependencies="odelib.lib fmodvc.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25_d.lib pthreadVSE2.lib pthreadVC2.lib Half.lib Iex.lib IlmImf.lib IlmThread.lib Imath.lib avcodec-51.lib avformat-52.lib avutil-49.lib swscale-0.lib"
+ AdditionalDependencies="odelib.lib fmodvc.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25_d.lib pthreadVSE2.lib pthreadVC2.lib Half.lib Iex.lib IlmImf.lib IlmThread.lib Imath.lib avcodec-51.lib avformat-52.lib avutil-49.lib swscale-0.lib avdevice-52.lib"
ShowProgress="0"
OutputFile="..\..\..\..\bin\debug\blenderplayer.exe"
LinkIncremental="2"
@@ -138,7 +138,7 @@
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\ghost\include;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\intern\openal\include;..\..\..\..\..\build\msvc_9\intern\opennl\include;..\..\..\..\..\build\msvc_9\intern\bmfont\include;..\..\..\..\..\build\msvc_9\intern\iksolver\include;..\..\..\..\..\build\msvc_9\intern\SoundSystem\include;..\..\..\..\..\build\msvc_9\extern\glew\include;..\..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\source\blender\include;..\..\..\..\source\blender\imbuf;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\blenkernel;..\..\..\..\source\blender\makesdna;..\..\..\..\source\blender\blenloader;..\..\..\..\source\blender\readblenfile;..\..\..\..\source\blender\render\extern\include;..\..\..\..\source\kernel\gen_system;..\..\..\..\source\kernel\gen_messaging;..\..\..\..\source\gameengine\ketsji;..\..\..\..\source\gameengine\Physics;..\..\..\..\source\gameengine\network;..\..\..\..\source\gameengine\rasterizer;..\..\..\..\source\gameengine\converter;..\..\..\..\source\gameengine\gamelogic;..\..\..\..\source\gameengine\expressions;..\..\..\..\source\gameengine\scenegraph;..\..\..\..\source\gameengine\Physics\Ode;..\..\..\..\source\gameengine\soundsystem;..\..\..\..\source\gameengine\ketsji\kxnetwork;..\..\..\..\source\gameengine\gameplayer\common;..\..\..\..\source\gameengine\soundsystem\snd_openal;..\..\..\..\source\gameengine\network\loopbacknetwork;..\..\..\..\source\gameengine\rasterizer\ras_openglrasterizer;..\..\..\..\source\gameengine\gameplayer\common\windows;..\..\..\..\source\sumo\include;..\..\..\..\source\sumo\fuzzics\include;..\..\..\..\source\blender\gpu;..\..\..\..\..\build\msvc_9\intern\guardedalloc\include"
- PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE"
+ PreprocessorDefinitions="WIN32,NDEBUG,_CONSOLE;WITH_FFMPEG"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
@@ -166,7 +166,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="odelib.lib fmodvc.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25_d.lib pthreadVSE2.lib pthreadVC2.lib Half.lib Iex.lib IlmImf.lib IlmThread.lib Imath.lib avcodec-51.lib avformat-52.lib avutil-49.lib swscale-0.lib"
+ AdditionalDependencies="odelib.lib fmodvc.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25_d.lib pthreadVSE2.lib pthreadVC2.lib Half.lib Iex.lib IlmImf.lib IlmThread.lib Imath.lib avcodec-51.lib avformat-52.lib avutil-49.lib swscale-0.lib avdevice-52.lib"
OutputFile="..\..\..\..\bin\blenderplayer.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
diff --git a/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj b/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj
index 726ab910e7c..2982f4ab820 100644
--- a/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj
+++ b/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj
@@ -42,7 +42,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\GameLogic;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\Rasterizer;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\gpu;..\..\..\source\kernel\gen_system;..\..\..\intern\string;..\..\..\intern\moto\include;..\..\..\intern\guardedalloc;..\..\..\intern\SoundSystem;..\..\..\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\GameLogic;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\Rasterizer;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\gpu;..\..\..\source\kernel\gen_system;..\..\..\intern\string;..\..\..\intern\moto\include;..\..\..\intern\guardedalloc;..\..\..\intern\SoundSystem;..\..\..\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;WITH_FFMPEG;__STDC_CONSTANT_MACROS"
StringPooling="false"
BasicRuntimeChecks="3"
@@ -113,7 +113,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\GameLogic;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\Rasterizer;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\gpu;..\..\..\source\kernel\gen_system;..\..\..\intern\string;..\..\..\intern\moto\include;..\..\..\intern\guardedalloc;..\..\..\intern\SoundSystem;..\..\..\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include"
+ AdditionalIncludeDirectories="..\..\..\..\lib\windows\python\include\python2.5;..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\lib\windows\pthreads\include;..\..\..\source\gameengine\Ketsji;..\..\..\source\gameengine\Expressions;..\..\..\source\gameengine\GameLogic;..\..\..\source\gameengine\SceneGraph;..\..\..\source\gameengine\Rasterizer;..\..\..\source\gameengine\Rasterizer\RAS_OpenGLRasterizer;..\..\..\source\gameengine\BlenderRoutines;..\..\..\source\blender\editors\include;..\..\..\source\blender\blenlib;..\..\..\source\blender\blenkernel;..\..\..\source\blender\makesdna;..\..\..\source\blender\imbuf;..\..\..\source\blender\python;..\..\..\source\blender\gpu;..\..\..\source\kernel\gen_system;..\..\..\intern\string;..\..\..\intern\moto\include;..\..\..\intern\guardedalloc;..\..\..\intern\SoundSystem;..\..\..\extern\glew\include;..\..\..\..\build\msvc_9\intern\guardedalloc\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;WITH_FFMPEG;__STDC_CONSTANT_MACROS"
StringPooling="true"
RuntimeLibrary="0"
diff --git a/release/freedesktop/blender.desktop b/release/freedesktop/blender.desktop
new file mode 100644
index 00000000000..39e0e3afe8e
--- /dev/null
+++ b/release/freedesktop/blender.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Encoding=UTF-8
+Name=Blender
+Comment=3D modeling, animation, rendering and post-production
+Exec=blender
+Icon=blender.png
+Terminal=false
+Type=Application
+Categories=Graphics;3DGraphics;
+MimeType=application/x-blender;
diff --git a/release/scripts/bpymodules/paths_svg2obj.py b/release/scripts/bpymodules/paths_svg2obj.py
index de40bea3191..d51fe74190d 100644
--- a/release/scripts/bpymodules/paths_svg2obj.py
+++ b/release/scripts/bpymodules/paths_svg2obj.py
@@ -1,7 +1,7 @@
# -*- coding: latin-1 -*-
"""
-SVG 2 OBJ translater, 0.5.9h
-Copyright (c) jm soler juillet/novembre 2004-april 2007,
+SVG 2 OBJ translater, 0.5.9n
+Copyright (c) jm soler juillet/novembre 2004-february 2009,
# ---------------------------------------------------------------
released under GNU Licence
for the Blender 2.42 Python Scripts Bundle.
@@ -20,7 +20,6 @@ en même temps que ce programme ; si ce n'est pas le cas, écrivez à la
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307, États-Unis.
-
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@@ -35,7 +34,7 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# ---------------------------------------------------------------
-
+#
#---------------------------------------------------------------------------
# Page officielle :
# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_svg.htm
@@ -253,15 +252,27 @@ Changelog:
0.5.9h : - 2007/5/2
- script was updated with the modifs by cambo
- - removed all debug statements
+ - removed all debug statements
- correction of a zero division error in the calc_arc function.
+ 0.5.9f: - 2007/15/7
+ - Correction de plusieurs bugs sur l'attributions des couleurs et le nommage
+ des courbes
+
+ 0.5.9i : - ??/??/??
+ - Patch externe réalisé sur blender.org project.
+
+ 0.5.9j : - 08/11/2008
+ 0.5.9k : - 14/01/2009
+ 0.5.9l : - 31/01/2009
+ 0.5.9n : - 01/02/2009
+
==================================================================================
=================================================================================="""
SHARP_IMPORT=0
SCALE=1
scale_=1
-DEBUG = 0#print
+DEBUG = 0
DEVELOPPEMENT=0
TESTCOLOR=0
@@ -533,7 +544,7 @@ def createCURVES(curves, name):
scene.objects.selected = []
if not SEPARATE_CURVES:
- c = Curve.New()
+ c = Curve.New()
c.setResolu(24)
MATNAME=[]
@@ -709,7 +720,6 @@ def circle(prp):
else : cx =float(prp['cx'])
if 'cy' not in prp: cy=0.0
else : cy =float(prp['cy'])
- #print prp.keys()
r = float(prp['r'])
D=['M',str(cx),str(cy+r),
'C',str(cx-r), str(cy+r*0.552),str(cx-0.552*r),str(cy+r), str(cx),str(cy+r),
@@ -852,7 +862,7 @@ def calc_arc (cpx,cpy, rx, ry, ang, fa , fs , x, y) :
#--------------------
# 0.3.9
#--------------------
-def curve_to_a(c,D,n0,CP): #A,a
+def curve_to_a(curves, c,D,n0,CP): #A,a
global SCALE
l=[float(D[c[1]+1]),float(D[c[1]+2]),float(D[c[1]+3]),
int(D[c[1]+4]),int(D[c[1]+5]),float(D[c[1]+6]),float(D[c[1]+7])]
@@ -866,8 +876,7 @@ def curve_to_a(c,D,n0,CP): #A,a
POINTS= calc_arc (CP[0],CP[1],
l[0], l[1], l[2]*(PI / 180.0),
l[3], l[4],
- l[5], l[6] )
- #if DEBUG == 1 : print POINTS
+ l[5], l[6] )
for p in POINTS :
B=Bez()
B.co=[ p[2][0],p[2][1], p[0][0],p[0][1], p[1][0],p[1][1]]
@@ -881,16 +890,23 @@ def curve_to_a(c,D,n0,CP): #A,a
BP.co[2]=BP.co[0]
BP.co[3]=BP.co[1]
CP=[l[5], l[6]]
+ #---------- 059m------------
+ if len(D)>c[1]+7 and D[c[1]+8] not in TAGcourbe :
+ c[1]+=7
+ curves,n0,CP=curve_to_a(curves, c, D, n0,CP)
+ #---------- 059m------------
return curves,n0,CP
-def move_to(c, D, n0,CP, proprietes):
+def move_to(curves, c, D, n0,CP, proprietes):
global DEBUG,TAGcourbe, LAST_ID
global USE_COLORS
l=[float(D[c[1]+1]),float(D[c[1]+2])]
+
if c[0]=='m':
l=[l[0]+CP[0],
l[1] + CP[1]]
+
if n0 in curves.ITEM:
n0+=1
CP=[l[0],l[1]]
@@ -917,14 +933,12 @@ def move_to(c, D, n0,CP, proprietes):
B.co=[CP[0],CP[1],CP[0],CP[1],CP[0],CP[1]]
B.ha=['L','C']
B.tag=c[0]
- curves.ITEM[n0].beziers_knot.append(B)
- #if DEBUG==1: print curves.ITEM[n0], CP
+ curves.ITEM[n0].beziers_knot.append(B)
return curves,n0,CP
-def close_z(c,D,n0,CP): #Z,z
+def close_z(curves, c,D,n0,CP): #Z,z
curves.ITEM[n0].flagUV[0]=1
if len(curves.ITEM[n0].beziers_knot)>1:
- #print len(curves.ITEM[n0].beziers_knot)
BP=curves.ITEM[n0].beziers_knot[-1]
BP0=curves.ITEM[n0].beziers_knot[0]
if BP.tag in ['c','C','s','S',]:
@@ -936,7 +950,7 @@ def close_z(c,D,n0,CP): #Z,z
n0-=1
return curves,n0,CP
-def curve_to_q(c,D,n0,CP): #Q,q
+def curve_to_q(curves, c,D,n0,CP): #Q,q
l=[float(D[c[1]+1]),float(D[c[1]+2]),float(D[c[1]+3]),float(D[c[1]+4])]
if c[0]=='q':
l=[l[0]+CP[0], l[1]+CP[1], l[2]+CP[0], l[3]+CP[1]]
@@ -948,15 +962,14 @@ def curve_to_q(c,D,n0,CP): #Q,q
BP.co[2]=BP.co[0]
BP.co[3]=BP.co[1]
curves.ITEM[n0].beziers_knot.append(B)
- #if DEBUG==1: print B.co,BP.co
CP=[l[2],l[3]]
#if DEBUG==1: pass
if len(D)>c[1]+5 and D[c[1]+5] not in TAGcourbe :
c[1]+=4
- curve_to_q(c, D, n0,CP)
+ curves,n0,CP=curve_to_q(curves, c, D, n0,CP)
return curves,n0,CP
-def curve_to_t(c,D,n0,CP): #T,t
+def curve_to_t(curves, c,D,n0,CP): #T,t
l=[float(D[c[1]+1]),float(D[c[1]+2])]
if c[0]=='t':
l=[l[0]+CP[0], l[1]+CP[1]]
@@ -970,11 +983,10 @@ def curve_to_t(c,D,n0,CP): #T,t
BP.co[2]=l0[2]
BP.co[3]=l0[3]
curves.ITEM[n0].beziers_knot.append(B)
- #if DEBUG==1: print B.co,BP.co
CP=[l[0],l[1]]
if len(D)>c[1]+3 and D[c[1]+3] not in TAGcourbe :
c[1]+=4
- curve_to_t(c, D, n0,CP)
+ curves,n0,CP=curve_to_t(curves, c, D, n0,CP)
return curves,n0,CP
#--------------------
@@ -985,7 +997,7 @@ def build_SYMETRIC(l):
Y=l[3]-(l[1]-l[3])
return X,Y
-def curve_to_s(c,D,n0,CP): #S,s
+def curve_to_s(curves, c,D,n0,CP): #S,s
l=[float(D[c[1]+1]),
float(D[c[1]+2]),
float(D[c[1]+3]),
@@ -1003,17 +1015,16 @@ def curve_to_s(c,D,n0,CP): #S,s
#--------------------
BP.co[2],BP.co[3]=build_SYMETRIC([BP.co[4],BP.co[5],BP.co[0],BP.co[1]])
curves.ITEM[n0].beziers_knot.append(B)
- #if DEBUG==1: print B.co,BP.co
#--------------------
# 0.4.3
#--------------------
CP=[l[2],l[3]]
if len(D)>c[1]+5 and D[c[1]+5] not in TAGcourbe :
c[1]+=4
- curve_to_c(c, D, n0,CP)
+ curves,n0,CP=curve_to_c(curves, c, D, n0,CP)
return curves,n0,CP
-def curve_to_c(c, D, n0,CP): #c,C
+def curve_to_c(curves, c, D, n0,CP): #c,C
l=[float(D[c[1]+1]),float(D[c[1]+2]),float(D[c[1]+3]),
float(D[c[1]+4]),float(D[c[1]+5]),float(D[c[1]+6])]
if c[0]=='c':
@@ -1030,6 +1041,8 @@ def curve_to_c(c, D, n0,CP): #c,C
l[5],
l[2],
l[3]] #plus toucher au 2-3
+
+
B.ha=['C','C']
B.tag=c[0]
BP=curves.ITEM[n0].beziers_knot[-1]
@@ -1037,32 +1050,38 @@ def curve_to_c(c, D, n0,CP): #c,C
BP.co[3]=l[1]
BP.ha[1]='C'
curves.ITEM[n0].beziers_knot.append(B)
- #if DEBUG==1: print B.co,BP.co
CP=[l[4],l[5]]
if len(D)>c[1]+7 and D[c[1]+7] not in TAGcourbe :
- c[1]+=6
- curve_to_c(c, D, n0,CP)
+ c[1]+=6
+ curves,n0,CP=curve_to_c(curves, c, D, n0,CP)
return curves,n0,CP
-def draw_line_l(c, D, n0,CP): #L,l
- l=[float(D[c[1]+1]),float(D[c[1]+2])]
+def draw_line_l(curves, c, D, n0,CP): #L,l
+
+ l=[float(D[c[1]+1]),float(D[c[1]+2])]
if c[0]=='l':
l=[l[0]+CP[0],
- l[1]+CP[1]]
+ l[1]+CP[1]]
B=Bez()
- B.co=[l[0],l[1],l[0],l[1],l[0],l[1]]
+ B.co=[l[0],l[1],
+ l[0],l[1],
+ l[0],l[1]]
+
B.ha=['L','L']
B.tag=c[0]
BP=curves.ITEM[n0].beziers_knot[-1]
BP.ha[1]='L'
+
curves.ITEM[n0].beziers_knot.append(B)
- CP=[B.co[0],B.co[1]]
+ CP=[B.co[4],B.co[5]]
+
if len(D)>c[1]+3 and D[c[1]+3] not in TAGcourbe :
c[1]+=2
- draw_line_l(c, D, n0,CP) #L
+ curves,n0,CP=draw_line_l(curves, c, D, n0,CP) #L
+
return curves,n0,CP
-def draw_line_h(c,D,n0,CP): #H,h
+def draw_line_h(curves, c,D,n0,CP): #H,h
if c[0]=='h':
l=[float(D[c[1]+1])+float(CP[0]),CP[1]]
else:
@@ -1077,7 +1096,7 @@ def draw_line_h(c,D,n0,CP): #H,h
CP=[l[0],l[1]]
return curves,n0,CP
-def draw_line_v(c,D,n0,CP): #V, v
+def draw_line_v(curves, c,D,n0,CP): #V, v
if c[0]=='v':
l=[CP[0], float(D[c[1]+1])+CP[1]]
else:
@@ -1121,17 +1140,31 @@ TAGtransform=['M','L','C','S','H','V','T','Q']
tagTRANSFORM=0
def wash_DATA(ndata):
- if ndata:
- #if DEBUG==1: print ndata
+ if ndata:
ndata = ndata.strip()
+
if ndata[0]==',':ndata=ndata[1:]
if ndata[-1]==',':ndata=ndata[:-1]
+
#--------------------
# 0.4.0 : 'e'
#--------------------
- i = ndata.find('-')
- if i != -1 and ndata[i-1] not in ' ,e':
- ndata=ndata.replace('-',',-')
+ ni=0
+ i = ndata.find('-',ni)
+ if i != -1:
+ while i>-1 :
+ i = ndata.find('-',ni)
+ # 059l ------
+ if i>0 :
+ if ndata[i-1] not in [' ',',','e']:
+ ndata=ndata[:i]+','+ndata[i:]
+ ni=i+2
+ else:
+ ni=i+1
+ elif i>-1:
+ ni=1
+ # 059l ------
+
ndata=ndata.replace(',,',',')
ndata=ndata.replace(' ',',')
ndata=ndata.split(',')
@@ -1153,7 +1186,7 @@ def list_DATA(DATA):
# borner les differents segments qui devront etre
# traites
# pour cela construire une liste avec chaque
- # la position de chaqe emplacement tag de type
+ # position de chaque emplacement tag de type
# commande path...
# ----------------------------------------
tagplace=[]
@@ -1169,8 +1202,10 @@ def list_DATA(DATA):
# d'apparition des tags
#------------------------------------------
tagplace.sort()
-
+
tpn=range(len(tagplace))
+
+
#--------------------
# 0.3.5 :: short data, only one tag
#--------------------
@@ -1179,14 +1214,18 @@ def list_DATA(DATA):
for t in tpn[:-1]:
DATA2.append(DATA[tagplace[t]:tagplace[t]+1])
ndata=DATA[tagplace[t]+1:tagplace[t+1]]
+
if DATA2[-1] not in ['z','Z'] :
ndata=wash_DATA(ndata)
DATA2.extend(ndata)
+
DATA2.append(DATA[tagplace[t+1]:tagplace[t+1]+1])
+
if DATA2[-1] not in ['z','Z'] and len(DATA)-1>=tagplace[t+1]+1:
ndata=DATA[tagplace[t+1]+1:]
ndata=wash_DATA(ndata)
DATA2.extend(ndata) #059a
+
else:
#--------------------
# 0.3.5 : short data,only one tag
@@ -1276,15 +1315,13 @@ def control_CONTAINT(txt):
nt0=txt[t0:t1+1]
t2=nt0[nt0.find('(')+1:-1]
val=nt0[:nt0.find('(')]
+
while t2.find(' ')!=-1:
t2=t2.replace(' ',' ')
- t2=t2.replace(' ',',')
+ while t2.find(', ')!=-1: #059l
+ t2=t2.replace(', ',',') #059l
- """
- t2=t2.split(',')
- for index, t in enumerate(t2):
- t2[index]=float(t)
- """
+ t2=t2.replace(' ',',')
t2=[float(t) for t in t2.split(',')]
if val=='rotate' :
@@ -1314,12 +1351,24 @@ def curve_FILL(Courbe,proprietes):
i= i+6
Courbe[n].color=[int(pr[i:i+2],16),int(pr[i+2:i+4],16),int(pr[i+4:i+6],16)]
Courbe[n].mat=1
- elif ';fill-opacity' in pr:
- i= pr.find('fill:')+5
- i2= pr.find(';',i)
- COLORNAME= pr[i:i2]
- Courbe[n].color=SVGCOLORNAMELIST[COLORNAME]
- Courbe[n].mat=1
+ elif ';fill-opacity' in pr:
+ if pr.find('fill:url')==-1:
+ i= pr.find('fill:')+5
+ i2= pr.find(';',i)
+ COLORNAME= pr[i:i2]
+ Courbe[n].color=SVGCOLORNAMELIST[COLORNAME]
+ Courbe[n].mat=1
+ elif 'color:' in pr:
+ i= pr.find('color:')+6
+ i2= pr.find(';',i)
+ COLORNAME= pr[i:i2]
+ Courbe[n].color=SVGCOLORNAMELIST[COLORNAME]
+ Courbe[n].mat=1
+ else :
+ COLORNAME= 'white'
+ Courbe[n].color=SVGCOLORNAMELIST[COLORNAME]
+ Courbe[n].mat=1
+
#----------------------------------------------
# 0.4.1 : apply transform stack
#----------------------------------------------
@@ -1367,9 +1416,8 @@ def filter(d):
def get_BOUNDBOX(BOUNDINGBOX,SVG):
if 'viewbox' not in SVG:
h=float(filter(SVG['height']))
- #if DEBUG==1 : print 'h : ',h
+
w=float(filter(SVG['width']))
- #if DEBUG==1 : print 'w :',w
BOUNDINGBOX['rec']=[0.0,0.0,w,h]
r=BOUNDINGBOX['rec']
BOUNDINGBOX['coef']=w/h
@@ -1444,7 +1492,6 @@ def build_HIERARCHY(t):
b=balisetype.index(t[t0+1])
if t[t0+2]=='-':
b=balisetype.index(t[t0+1])+1
- #print t[t0:t1]
balise=BALISES[b]
if b==2:
parent=STACK.pop(-1)
@@ -1465,12 +1512,8 @@ def build_HIERARCHY(t):
if balise=='E' or balise=='O':
proprietes=collect_ATTRIBUTS(t[t0:t1+ouvrante])
- #print proprietes
if 'id' in proprietes:
LAST_ID=proprietes['id']
- #print LAST_ID
-
-
if balise=='O' and 'transform' in proprietes:
STACK.append(proprietes['transform'])
@@ -1489,20 +1532,20 @@ def build_HIERARCHY(t):
# 0.5.8, to remove exec
#--------------------
D=OTHERSSHAPES[proprietes['TYPE']](proprietes)
-
+ CP=[0.0,0.0]
if len(D)>0:
cursor=0
proprietes['n']=[]
for cell in D:
- #if DEBUG==2 : print 'cell : ',cell ,' --'
+
if len(cell)>=1 and cell[0] in TAGcourbe:
#--------------------
# 0.5.8, to remove exec
#--------------------
if cell[0] in ['m','M']:
- curves,n0,CP=Actions[cell]([cell,cursor], D, n0,CP,proprietes)
+ curves,n0,CP=Actions[cell](curves, [cell,cursor], D, n0,CP,proprietes)
else:
- curves,n0,CP=Actions[cell]([cell,cursor], D, n0,CP)
+ curves,n0,CP=Actions[cell](curves, [cell,cursor], D, n0,CP)
cursor+=1
if TRANSFORM>0 or 'transform' in proprietes :
@@ -1513,7 +1556,6 @@ def build_HIERARCHY(t):
elif proprietes['TYPE'] == 'svg':
- #print 'proprietes.keys()',proprietes.keys()
BOUNDINGBOX = get_BOUNDBOX(BOUNDINGBOX,proprietes)
else:
#--------------------
diff --git a/release/scripts/export_fbx.py b/release/scripts/export_fbx.py
index 6f964118964..730776bf1b8 100644
--- a/release/scripts/export_fbx.py
+++ b/release/scripts/export_fbx.py
@@ -1446,13 +1446,13 @@ def write(filename, batch_objects = None, \
for f in me.faces:
for col in f.col:
if i==-1:
- file.write('%i,%i,%i,255' % (col[0], col[1], col[2]))
+ file.write('%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0))
i=0
else:
if i==7:
file.write('\n\t\t\t\t')
i=0
- file.write(',%i,%i,%i,255' % (col[0], col[1], col[2]))
+ file.write(',%.4f,%.4f,%.4f,1' % (col[0]/255.0, col[1]/255.0, col[2]/255.0))
i+=1
ii+=1 # One more Color
diff --git a/release/scripts/export_obj.py b/release/scripts/export_obj.py
index 9feb02638c3..28e1443e953 100644
--- a/release/scripts/export_obj.py
+++ b/release/scripts/export_obj.py
@@ -120,7 +120,7 @@ def write_mtl(filename):
if img: # We have an image on the face!
file.write('map_Kd %s\n' % img.filename.split('\\')[-1].split('/')[-1]) # Diffuse mapping image
- elif not mat: # No face image. if we havea material search for MTex image.
+ elif mat: # No face image. if we havea material search for MTex image.
for mtex in mat.getTextures():
if mtex and mtex.tex.type == Blender.Texture.Types.IMAGE:
try:
diff --git a/release/scripts/import_dxf.py b/release/scripts/import_dxf.py
index 6a1981bb262..c3203891c60 100644
--- a/release/scripts/import_dxf.py
+++ b/release/scripts/import_dxf.py
@@ -7,7 +7,7 @@ Group: 'Import'
Tooltip: 'Import for DXF geometry data (Drawing eXchange Format).'
"""
__author__ = 'Kitsu(Ed Blake) & migius(Remigiusz Fiedler)'
-__version__ = '1.12 - 2008.11.16 by migius'
+__version__ = '1.12 - 2009.03.14 by migius'
__url__ = ["http://blenderartists.org/forum/showthread.php?t=84319",
"http://wiki.blender.org/index.php/Scripts/Manual/Import/DXF-3D"]
__email__ = ["migius(at)4d-vectors.de","Kitsune_e(at)yahoo.com"]
@@ -15,7 +15,7 @@ __bpydoc__ = """\
This script imports objects from DXF (2d/3d) into Blender.
This script imports 2d and 3d geometery from DXF files.
-Supported DXF format versions: from (r2.5) r12 up to 2008.
+Supported DXF format versions: from (r2.5) r12 up to r2008.
Enhanced features are:
- configurable object filtering and geometry manipulation,
- configurable material pre-processing,
@@ -32,7 +32,7 @@ MINSERT (=array of blocks),
CIRCLE,
ARC,
3DFACE,
-2d-POLYLINE (=plane, incl. arc, variable-width, curve, spline),
+2d-POLYLINE (=in plane, incl. arc, variable-width, curve, spline),
3d-POLYLINE (=non-plane),
3d-POLYMESH,
3d-POLYFACE,
@@ -57,7 +57,7 @@ Supported layout modes:
"model space" is default,
"paper space" as option (= "layout views")
-Supported scene definition objescts produced with AVE_RENDER:
+Supported scene definition objects produced with AVE_RENDER:
scene: selection of lights assigned to the camera,
lights: DIRECT, OVERHEAD, SH_SPOT,
(wip v1.13 import of AVE_RENDER material definitions)
@@ -88,7 +88,7 @@ in creating new objects in scene database - probably a database management probl
"""
History:
- v1.0 - 2007/2008 by migius
+ v1.0 - 2007/2008/2009 by migius
planned tasks:
-- (to see more, search for "--todo--" in script code)
-- command-line-mode/batch-mode
@@ -111,6 +111,11 @@ History:
-- support ortho mode for VIEWs and VPORTs as cameras
+ v1.12 - 2009.03.14 by migius
+ d3 removed all set()functions (problem with osx/python<2.4 reported by Blinkozo)
+ d3 code-cleaning
+ v1.12 - 2009.01.14 by migius
+ d2 temp patch for noname BLOCKS (*X,*U,*D)
v1.12 - 2008.11.16 by migius
d1 remove try_finally: cause not supported in python <2.5
d1 add Bezier curves bevel radius support (default 1.0)
@@ -309,9 +314,17 @@ from dxfReader import readDXF
#from dxfReader import get_name, get_layer
from dxfReader import Object as dxfObject
from dxfColorMap import color_map
-
from math import *
+# osx-patch by Blinkozo
+#todo: avoid additional modules, prefer Blender-build-in test routines
+#import platform
+#if platform.python_version() < '2.4':
+# from sets import Set as set
+#from sys import version_info
+#ver = '%s.%s' % version_info[0:2]
+# end osx-patch
+
try:
import os
if os.name != 'mac':
@@ -950,7 +963,7 @@ class Point: #-----------------------------------------------------------------
if thic < settings.var['dist_min']: thic = settings.var['dist_min']
if points_as in [1,3,4,5]:
- if True: # points_as in [1,5]: # as 'empty'
+ if points_as in [1,5]: # as 'empty'
c = 'Empty'
elif points_as == 3: # as 'thin sphere'
res = settings.var['thin_res']
@@ -1276,66 +1289,6 @@ class Polyline: #--------------------------------------------------------------
pline = Curve.New(obname) # create new curve data
#pline.setResolu(24) #--todo-----
- if False: #old self.spline: # NURBSplines-----OK-----
- #print 'deb:polyline2dCurve.draw self.spline!' #---------------
- weight1 = 0.5
- weight2 = 1.0
- if self.curvQuadrati:
- # Bezier-curve form simulated in NURBS-curve
- # generate middlepoints except start/end-segments ---
- #print 'deb:polyline2dCurve.draw extraQBspline!' #---------------
- temp_points = []
- point = d_points[0].loc
- point.append(weight1)
- temp_points.append(point)
- for i in xrange(1,len(d_points)-2):
- point1 = d_points[i].loc
- point2 = d_points[i+1].loc
- mpoint = list((Mathutils.Vector(point1) + Mathutils.Vector(point2)) * 0.5)
- mpoint.append(weight2)
- point1.append(weight1)
- temp_points.append(point1)
- temp_points.append(mpoint)
- point2.append(weight1)
- temp_points.append(point2)
- point = d_points[-1].loc
- point.append(weight1)
- temp_points.append(point)
- d_points = temp_points
- else:
- temp_points = []
- for d in d_points:
- d = d.loc
- d.append(weight1)
- temp_points.append(d)
- d_points = temp_points
-
- if not self.closed:
- # generate extended startpoint and endpoint------
- point1 = Mathutils.Vector(d_points[0][:3])
- point2 = Mathutils.Vector(d_points[1][:3])
- startpoint = list(point1 - point2 + point1)
- startpoint.append(weight1)
- point1 = Mathutils.Vector(d_points[-1][:3])
- point2 = Mathutils.Vector(d_points[-2][:3])
- endpoint = list(point1 - point2 + point1)
- endpoint.append(weight1)
- temp_points = []
- temp_points.append(startpoint)
- temp_points.extend(d_points)
- d_points = temp_points
- d_points.append(endpoint)
-
- point = d_points[0]
- curve = pline.appendNurb(point)
- curve.setType(4) #NURBS curve
- for point in d_points[1:]:
- curve.append(point)
- if self.closed:
- curve.flagU = 1 # Set curve cyclic=close
- else:
- curve.flagU = 0 # Set curve not cyclic=open
-
if self.spline: # NURBSplines-----OK-----
#print 'deb:polyline2dCurve.draw self.spline!' #---------------
nurbs_points = []
@@ -1358,21 +1311,6 @@ class Polyline: #--------------------------------------------------------------
except AttributeError: pass
#print 'deb: dir(curve):', dir(curve) #----------------
- elif False: #orig self.curved: #--Bezier-curves---OK-------
- #print 'deb:polyline2dCurve.draw self.curved!' #---------------
- curve = pline.appendNurb(BezTriple.New(d_points[0]))
- for p in d_points[1:]:
- curve.append(BezTriple.New(p))
- for point in curve:
- point.handleTypes = [AUTO, AUTO]
- point.radius = 1.0
- if self.closed:
- curve.flagU = 1 # Set curve cyclic=close
- else:
- curve.flagU = 0 # Set curve not cyclic=open
- curve[0].handleTypes = [FREE, ALIGN] #remi--todo-----
- curve[-1].handleTypes = [ALIGN, FREE] #remi--todo-----
-
elif self.curved: #--SPLINE as Bezier-curves---wip------
#print 'deb:polyline2dCurve.draw self.curved!' #---------------
begtangent, endtangent = None, None
@@ -1424,68 +1362,48 @@ class Polyline: #--------------------------------------------------------------
for i in xrange(len(d_points)):
point1 = d_points[i]
#point2 = d_points[i+1]
- if False: #-----outdated!- standard calculation ----------------------------------
- if point1.bulge and (i < len(d_points)-2 or self.closed):
- verts, center = calcBulge(point1, point2, arc_res, triples=False)
- if i == 0: curve = pline.appendNurb(BezTriple.New(verts[0]))
- else: curve.append(BezTriple.New(verts[0]))
- curve[-1].handleTypes = [VECT, VECT] #--todo--calculation of bezier-tangents
- curve[-1].radius = 1.0
- for p in verts[1:]:
- curve.append(BezTriple.New(p))
- curve[-1].handleTypes = [AUTO, AUTO]
- curve[-1].radius = 1.0
- else:
- if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
- else: curve.append(BezTriple.New(point1.loc))
- curve[-1].handleTypes = [VECT, VECT] #--todo--calculation of bezier-tangents
- curve[-1].radius = 1.0
+ #----- optimised Bezier-Handles calculation --------------------------------
+ #print 'deb:drawPlineCurve: i:', i #---------
+ if point1.bulge and not (i == len(d_points)-1 and point1.bulge and not self.closed):
+ if i == len(d_points)-1: point2 = d_points[0]
+ else: point2 = d_points[i+1]
- elif True: #----- optimised Bezier-Handles calculation --------------------------------
- #print 'deb:drawPlineCurve: i:', i #---------
- if point1.bulge and not (i == len(d_points)-1 and point1.bulge and not self.closed):
- if i == len(d_points)-1: point2 = d_points[0]
- else: point2 = d_points[i+1]
+ # calculate additional points for bulge
+ VectorTriples = calcBulge(point1, point2, arc_res, triples=True)
- # calculate additional points for bulge
- VectorTriples = calcBulge(point1, point2, arc_res, triples=True)
+ if prevHandleType == FREE:
+ #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
+ VectorTriples[0][:3] = prevHandleVect
+ #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
- if prevHandleType == FREE:
- #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
- VectorTriples[0][:3] = prevHandleVect
- #print 'deb:drawPlineCurve: VectorTriples[0]:', VectorTriples[0] #---------
+ if i == 0: curve = pline.appendNurb(BezTriple.New(VectorTriples[0]))
+ else: curve.append(BezTriple.New(VectorTriples[0]))
+ curve[-1].handleTypes = [prevHandleType, FREE]
+ curve[-1].radius = 1.0
- if i == 0: curve = pline.appendNurb(BezTriple.New(VectorTriples[0]))
- else: curve.append(BezTriple.New(VectorTriples[0]))
- curve[-1].handleTypes = [prevHandleType, FREE]
+ for p in VectorTriples[1:-1]:
+ curve.append(BezTriple.New(p))
+ curve[-1].handleTypes = [FREE, FREE]
curve[-1].radius = 1.0
- for p in VectorTriples[1:-1]:
- curve.append(BezTriple.New(p))
- curve[-1].handleTypes = [FREE, FREE]
- curve[-1].radius = 1.0
-
- prevHandleVect = VectorTriples[-1][:3]
- prevHandleType = FREE
- #print 'deb:drawPlineCurve: prevHandleVect:', prevHandleVect #---------
+ prevHandleVect = VectorTriples[-1][:3]
+ prevHandleType = FREE
+ #print 'deb:drawPlineCurve: prevHandleVect:', prevHandleVect #---------
+ else:
+ #print 'deb:drawPlineCurve: else' #----------
+ if prevHandleType == FREE:
+ VectorTriples = prevHandleVect + list(point1) + list(point1)
+ #print 'deb:drawPlineCurve: VectorTriples:', VectorTriples #---------
+ curve.append(BezTriple.New(VectorTriples))
+ curve[-1].handleTypes = [FREE, VECT]
+ prevHandleType = VECT
+ curve[-1].radius = 1.0
else:
- #print 'deb:drawPlineCurve: else' #----------
- if prevHandleType == FREE:
- VectorTriples = prevHandleVect + list(point1) + list(point1)
- #print 'deb:drawPlineCurve: VectorTriples:', VectorTriples #---------
- curve.append(BezTriple.New(VectorTriples))
- curve[-1].handleTypes = [FREE, VECT]
- prevHandleType = VECT
- curve[-1].radius = 1.0
- else:
- if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
- else: curve.append(BezTriple.New(point1.loc))
- curve[-1].handleTypes = [VECT, VECT]
- curve[-1].radius = 1.0
-
-
-
+ if i == 0: curve = pline.appendNurb(BezTriple.New(point1.loc))
+ else: curve.append(BezTriple.New(point1.loc))
+ curve[-1].handleTypes = [VECT, VECT]
+ curve[-1].radius = 1.0
#print 'deb:drawPlineCurve: curve[-1].vec[0]', curve[-1].vec[0] #----------
if self.closed:
@@ -1584,23 +1502,6 @@ class Polyline: #--------------------------------------------------------------
d_points = self.doubles_out(settings, d_points)
#print 'deb:drawPolyCurve d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
- """# routine to sort out of "double.vertices" ------------------------------------
- minimal_dist = settings.var['dist_min'] * 0.1
- temp_points = []
- for i in xrange(len(d_points)-1):
- point = d_points[i]
- point2 = d_points[i+1]
- #print 'deb:double.vertex p1,p2', point, point2 #------------------------
- delta = Mathutils.Vector(point2.loc) - Mathutils.Vector(point.loc)
- if delta.length > minimal_dist:
- temp_points.append(point)
- #else: print 'deb:drawPoly2d double.vertex sort out!' #------------------------
- temp_points.append(d_points[-1]) #------ incl. last vertex -------------
- #if self.closed: temp_points.append(d_points[1]) #------ loop start vertex -------------
- d_points = temp_points #-----vertex.list without "double.vertices"
- #print 'deb:drawPoly2d d_pointsList =after DV-outsorting=====:\n ', d_points #------------------------
- """
-
#print 'deb:drawPoly2d len of d_pointsList ====== ', len(d_points) #------------------------
if len(d_points) < 2: #if too few vertex, then return
#print 'deb:drawPoly2d corrupted Vertices' #---------
@@ -1796,29 +1697,6 @@ class Polyline: #--------------------------------------------------------------
# clean corner intersection
pointsLc.append(cornerpointL)
pointsRc.append(cornerpointR)
- elif False: # the standard no-intersection
- # --todo-- not optimal, because produces X-face
- pointsLc.extend((pointsLe[i],pointsLs[i+1]))
- pointsRc.extend((pointsRe[i],pointsRs[i+1]))
- elif False: # --todo-- the optimised non-intersection
- if (cornerpointL - vecL1).length < (cornerpointR - vecR1).length:
- left_angle = True
- else:
- left_angle = False
- limit_dist = settings.var['dist_min']
- if left_angle: # if left turning angle
- #print 'deb:drawPoly2d it is left turning angle' #-------------
- # to avoid triangelface/doubleVertex
- delta1 = (cornerpointL - vecL1).normalize() * limit_dist
- delta4 = (cornerpointL - vecL4).normalize() * limit_dist
- pointsLc.extend((cornerpointL - delta1, cornerpointL - delta4))
- pointsRc.extend((pointsRe[i],pointsRs[i+1]))
- else: # if right turning angle
- #print 'deb:drawPoly2d right turning angle' #-------------
- delta1 = (cornerpointR - vecR1).normalize() * limit_dist
- delta4 = (cornerpointR - vecR4).normalize() * limit_dist
- pointsRc.extend((cornerpointR - delta1, cornerpointR - delta4))
- pointsLc.extend((pointsLe[i],pointsLs[i+1]))
else:
pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
@@ -1855,14 +1733,10 @@ class Polyline: #--------------------------------------------------------------
vecR3, vecR4 = pointsRs[i+1], pointsRe[i+1]
if bulg_points[i] != None:
#compute left- and right-cornerpoints
- if True:
- cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
- cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
- pointsLc.append(cornerpointL[0])
- pointsRc.append(cornerpointR[0])
- else:
- pointVec = Mathutils.Vector(point[i])
-
+ cornerpointL = Mathutils.LineIntersect(vecL1, vecL2, vecL3, vecL4)
+ cornerpointR = Mathutils.LineIntersect(vecR1, vecR2, vecR3, vecR4)
+ pointsLc.append(cornerpointL[0])
+ pointsRc.append(cornerpointR[0])
else: # IF non-bulg
pointsLc.extend((pointsLe[i],points[i+1],pointsLs[i+1]))
pointsRc.extend((pointsRe[i],points[i+1],pointsRs[i+1]))
@@ -1924,21 +1798,20 @@ class Polyline: #--------------------------------------------------------------
for v in f_right: vg_right.extend(v)
for v in f_top: vg_top.extend(v)
for v in f_bottom: vg_bottom.extend(v)
- me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', list(set(vg_left)), 1.0, replace)
- me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', list(set(vg_right)), 1.0, replace)
- me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace)
- me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace)
+ me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace)
+ me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace)
+ me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
+ me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
if not self.closed:
me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', f_end[0], 1.0, replace)
if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
#if self.spline or self.curved:
- if True:
- smooth_len = len(f_left) + len(f_right)
- for i in xrange(smooth_len):
- me.faces[i].smooth = True
- #me.Modes(AUTOSMOOTH)
+ smooth_len = len(f_left) + len(f_right)
+ for i in xrange(smooth_len):
+ me.faces[i].smooth = True
+ #me.Modes(AUTOSMOOTH)
# 2.level:IF width, but no-thickness ---------------------
else:
@@ -1977,10 +1850,9 @@ class Polyline: #--------------------------------------------------------------
if settings.var['meshSmooth_on']: # left and right side become smooth ----------------------
#if self.spline or self.curved:
- if True:
- for i in xrange(len(faces)):
- me.faces[i].smooth = True
- #me.Modes(AUTOSMOOTH)
+ for i in xrange(len(faces)):
+ me.faces[i].smooth = True
+ #me.Modes(AUTOSMOOTH)
# 1.level:IF no-width and no-thickness ---------------------
else:
@@ -2684,38 +2556,17 @@ class Circle: #----------------------------------------------------------------
cyl_rad = 0.5 * settings.var['width_min']
if settings.var['lines_as'] == 5: # draw CIRCLE as curve -------------
- if True: # universal version
- arc_res = settings.var['curve_arc']
- #arc_res = 3
- start, end = 0.0, 360.0
- VectorTriples = calcArc(None, radius, start, end, arc_res, True)
- c = Curve.New(obname) # create new curve data
- curve = c.appendNurb(BezTriple.New(VectorTriples[0]))
- for p in VectorTriples[1:-1]:
- curve.append(BezTriple.New(p))
- for point in curve:
- point.handleTypes = [FREE, FREE]
- point.radius = 1.0
- else: # standard version
- c = Curve.New(obname) # create new curve data
- p1 = (0, -radius, 0)
- p2 = (radius, 0, 0)
- p3 = (0, radius, 0)
- p4 = (-radius, 0, 0)
-
- p1 = BezTriple.New(p1)
- p2 = BezTriple.New(p2)
- p3 = BezTriple.New(p3)
- p4 = BezTriple.New(p4)
-
- curve = c.appendNurb(p1)
- curve.append(p2)
- curve.append(p3)
- curve.append(p4)
- for point in curve:
- point.handleTypes = [AUTO, AUTO]
- point.radius = 1.0
-
+ arc_res = settings.var['curve_arc']
+ #arc_res = 3
+ start, end = 0.0, 360.0
+ VectorTriples = calcArc(None, radius, start, end, arc_res, True)
+ c = Curve.New(obname) # create new curve data
+ curve = c.appendNurb(BezTriple.New(VectorTriples[0]))
+ for p in VectorTriples[1:-1]:
+ curve.append(BezTriple.New(p))
+ for point in curve:
+ point.handleTypes = [FREE, FREE]
+ point.radius = 1.0
curve.flagU = 1 # 1 sets the curve cyclic=closed
if settings.var['fill_on']:
c.setFlag(6) # 2+4 set top and button caps
@@ -2737,24 +2588,6 @@ class Circle: #----------------------------------------------------------------
ob.SizeZ *= abs(thic)
return ob
- elif False: # create a new mesh_object with buildin_circle_primitive
- verts_num = settings.var['arc_res'] * sqrt(radius / settings.var['arc_rad'])
- if verts_num > 100: verts_num = 100 # Blender accepts only values [3:500]
- if verts_num < 4: verts_num = 4 # Blender accepts only values [3:500]
- if thic != 0:
- loc2 = thic * 0.5 #-----blenderAPI draw Cylinder with 2*thickness
- self.loc[2] += loc2 #---new location for the basis of cylinder
- #print 'deb:circleDraw:self.loc2:', self.loc #-----------------------
- c = Mesh.Primitives.Cylinder(int(verts_num), radius*2, abs(thic))
- else:
- c = Mesh.Primitives.Circle(int(verts_num), radius*2)
-
- #c.update()
- ob = SCENE.objects.new(c, obname) # create a new circle_mesh_object
- ob.loc = tuple(self.loc)
- transform(self.extrusion, 0, ob)
- return ob
-
else: # draw CIRCLE as mesh -----------------------------------------------
if M_OBJ: obname, me, ob = makeNewObject()
else:
@@ -2810,12 +2643,13 @@ class Circle: #----------------------------------------------------------------
replace = Blender.Mesh.AssignModes.REPLACE #or .AssignModes.ADD
vg_band, vg_top, vg_bottom = [], [], []
for v in f_band: vg_band.extend(v)
- me.addVertGroup('side.band') ; me.assignVertsToGroup('side.band', list(set(vg_band)), 1.0, replace)
+ me.addVertGroup('side.band') ; me.assignVertsToGroup('side.band', vg_band, 1.0, replace)
+
if settings.var['fill_on']:
for v in f_top: vg_top.extend(v)
for v in f_bottom: vg_bottom.extend(v)
- me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace)
- me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace)
+ me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
+ me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
else: # if thic == 0
if settings.var['fill_on']:
@@ -2992,10 +2826,10 @@ class Arc: #-----------------------------------------------------------------
for v in f_right: vg_right.extend(v)
for v in f_top: vg_top.extend(v)
for v in f_bottom: vg_bottom.extend(v)
- me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', list(set(vg_left)), 1.0, replace)
- me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', list(set(vg_right)), 1.0, replace)
- me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace)
- me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace)
+ me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace)
+ me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace)
+ me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
+ me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', f_end[0], 1.0, replace)
@@ -3247,8 +3081,6 @@ class Insert: #----------------------------------------------------------------
if a_data.key == 'SCENE': # define set of lights as blender group
scene_lights = 1
- elif False: # define set of lights as blender group
- scene_lights = 1
return
elif name == 'ave_global':
if settings.var['lights_on']: #if lights support activated
@@ -3409,35 +3241,12 @@ class Ellipse: #---------------------------------------------------------------
obname = obname[:MAX_NAMELENGTH]
center = self.loc
- if True:
- start = degrees(self.start_angle)
- end = degrees(self.end_angle)
- if abs(end - 360.0) < 0.00001: end = 360.0
- ellipse_closed = False
- if end - start == 360.0: ellipse_closed = True
+ start = degrees(self.start_angle)
+ end = degrees(self.end_angle)
+ if abs(end - 360.0) < 0.00001: end = 360.0
+ ellipse_closed = False
+ if end - start == 360.0: ellipse_closed = True
- else: # bug in AutoCAD_2002 dxf-exporter into r12 for ELLIPSE->POLYLINE_ARC
- #print 'deb:calcEllipse---------:\n start=%s\n end=%s' %(self.start_angle, self.end_angle) #---------
- if self.start_angle > pi+pi: self.start_angle %= pi+pi
- if self.end_angle > pi+pi: self.end_angle %= pi+pi
- if abs(self.end_angle - pi - pi) < 0.00001: self.end_angle = pi + pi
- ellipse_closed = False
- if abs(self.end_angle - self.start_angle) == pi + pi: ellipse_closed = True
- test = self.start_angle % pi
- if test < 0.001 or pi - test < 0.001: start = self.start_angle
- else:
- start = atan(tan(self.start_angle) * self.ratio)
- if start < 0.0: start += pi
- if self.start_angle > pi: start += pi
- test = self.end_angle % pi
- if test < 0.001 or pi - test < 0.001: end = self.end_angle
- else:
- end = atan(tan(self.end_angle) * self.ratio)
- if end < 0.0: end += pi
- if self.end_angle > pi: end += pi
- start = degrees(start)
- end = degrees(end)
-
# rotation = Angle between major and WORLDX
# doesnt work, couse produces always positive value: rotation = Mathutils.AngleBetweenVecs(major, WORLDX)
if self.major[0] == 0:
@@ -3512,8 +3321,6 @@ class Ellipse: #---------------------------------------------------------------
verts = calcArc(None, radius, start, end, arc_res, False)
#verts = [list(point) for point in verts]
- if False: #--todo--: if ellipse_closed:
- verts = verts[:-1] #list without last point/edge (cause closed curve)
len1 = len(verts)
#print 'deb:len1:', len1 #-----------------------
if width != 0:
@@ -3563,10 +3370,10 @@ class Ellipse: #---------------------------------------------------------------
for v in f_right: vg_right.extend(v)
for v in f_top: vg_top.extend(v)
for v in f_bottom: vg_bottom.extend(v)
- me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', list(set(vg_left)), 1.0, replace)
- me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', list(set(vg_right)), 1.0, replace)
- me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', list(set(vg_top)), 1.0, replace)
- me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',list(set(vg_bottom)), 1.0, replace)
+ me.addVertGroup('side.left') ; me.assignVertsToGroup('side.left', vg_left, 1.0, replace)
+ me.addVertGroup('side.right') ; me.assignVertsToGroup('side.right', vg_right, 1.0, replace)
+ me.addVertGroup('side.top') ; me.assignVertsToGroup('side.top', vg_top, 1.0, replace)
+ me.addVertGroup('side.bottom'); me.assignVertsToGroup('side.bottom',vg_bottom, 1.0, replace)
me.addVertGroup('side.start'); me.assignVertsToGroup('side.start', f_start[0], 1.0, replace)
me.addVertGroup('side.end') ; me.assignVertsToGroup('side.end', f_end[0], 1.0, replace)
@@ -4378,8 +4185,9 @@ def analyzeDXF(dxfFile): #---------------------------------------
for item2 in drawing.entities.data:
if type(item2) != list and item2.type == 'insert':
- if not layersmap or (layersmap and not layersmap[item2.layer][1]): #if insert_layer is not frozen
- blocksmap[item2.name][0] = True # marked as world used BLOCK
+ if item2.name in blocksmap.keys():
+ if not layersmap or (layersmap and not layersmap[item2.layer][1]): #if insert_layer is not frozen
+ blocksmap[item2.name][0] = True # marked as world used BLOCK
key_list = blocksmap.keys()
key_list.reverse()
@@ -4789,10 +4597,12 @@ def drawer(_type, entities, settings, block_def): #----------------------------
group = getGroup('l:%s' % layernamesmap[entity.layer])
if _type == 'insert': #---- INSERT and MINSERT=array --------------------
- if not settings.var['block_nn'] and entity.name.startswith('*X'): #---- support for noname BLOCKs
- #print 'deb:drawer entity.name:', entity.name #------------
- continue
- elif settings.var['blockFilter_on'] and not settings.accepted_block(entity.name):
+ if not settings.var['block_nn']: #----turn off support for noname BLOCKs
+ prefix = entity.name[:2]
+ if prefix in ('*X', '*U', '*D'):
+ #print 'deb:drawer entity.name:', entity.name #------------
+ continue
+ if settings.var['blockFilter_on'] and not settings.accepted_block(entity.name):
continue
#print 'deb:insert entity.loc:', entity.loc #----------------
diff --git a/release/scripts/import_obj.py b/release/scripts/import_obj.py
index 3aad0800cf7..42cdac4dc35 100644
--- a/release/scripts/import_obj.py
+++ b/release/scripts/import_obj.py
@@ -424,8 +424,8 @@ def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES, verts_l
sharp_edges[key]= None
- # mat the material names to an index
- material_mapping= dict([(name, i) for i, name in enumerate(unique_materials.keys())])
+ # map the material names to an index
+ material_mapping= dict([(name, i) for i, name in enumerate(unique_materials)]) # enumerate over unique_materials keys()
materials= [None] * len(unique_materials)
diff --git a/release/scripts/import_web3d.py b/release/scripts/import_web3d.py
index 28bc1a40ef0..87a259cbe56 100755
--- a/release/scripts/import_web3d.py
+++ b/release/scripts/import_web3d.py
@@ -1758,7 +1758,7 @@ def importMesh_IndexedFaceSet(geom, bpyima, ancestry):
print '\tWarning: per vertex color index out of range'
continue
- if len(ifs_vcol) < color_index:
+ if color_index < len(ifs_vcol):
c.r, c.g, c.b = ifs_vcol[color_index]
else:
#print '\tWarning: per face color index out of range'
diff --git a/release/scripts/ply_import.py b/release/scripts/ply_import.py
index 302e21a0a43..43129ec01e9 100644
--- a/release/scripts/ply_import.py
+++ b/release/scripts/ply_import.py
@@ -160,13 +160,16 @@ def read(filename):
obj_spec = object_spec()
try:
- file = open(filename, 'rb')
+ file = open(filename, 'rU') # Only for parsing the header, not binary data
signature = file.readline()
- if (signature != 'ply\n'):
+
+ if not signature.startswith('ply'):
print 'Signature line was invalid'
return None
+
while 1:
tokens = re.split(r'[ \n]+', file.readline())
+
if (len(tokens) == 0):
continue
if (tokens[0] == 'end_header'):
@@ -197,14 +200,22 @@ def read(filename):
obj_spec.specs[-1].properties.append(property_spec(tokens[4], type_specs[tokens[2]], type_specs[tokens[3]]))
else:
obj_spec.specs[-1].properties.append(property_spec(tokens[2], None, type_specs[tokens[1]]))
+
+ if format != 'ascii':
+ file.close() # was ascii, now binary
+ file = open(filename, 'rb')
+
+ # skip the header...
+ while not file.readline().startswith('end_header'):
+ pass
+
obj = obj_spec.load(format_specs[format], file)
-
+
except IOError, (errno, strerror):
try: file.close()
except: pass
return None
-
try: file.close()
except: pass
diff --git a/release/scripts/scripttemplate_gamelogic.py b/release/scripts/scripttemplate_gamelogic.py
index 7184d7e424f..01348e86d0a 100644
--- a/release/scripts/scripttemplate_gamelogic.py
+++ b/release/scripts/scripttemplate_gamelogic.py
@@ -11,6 +11,9 @@ import bpy
script_data = \
'''
+# This script must be assigned to a python controller
+# where it can access the object that owns it and the sensors/actuators that it connects to.
+
# GameLogic has been added to the global namespace no need to import
# for keyboard event comparison
@@ -50,7 +53,7 @@ def main():
for actu in cont.getActuators():
# The actuator can be on another object, we may want to use it
own_actu = actu.getOwner()
- print ' actuator:', sens.getName()
+ print ' actuator:', actu.getName()
# This runs the actuator or turns it off
# note that actuators will continue to run unless explicitly turned off.
diff --git a/source/Makefile b/source/Makefile
index 90e93d55f6e..e8ec090255c 100644
--- a/source/Makefile
+++ b/source/Makefile
@@ -89,7 +89,6 @@ GRPLIB += $(OCGDIR)/blender/radiosity/$(DEBUG_DIR)libradiosity.a
# to properly resolve circular dependencies. ugly, but it works...
# the repeat entries could probably be trimmed down.
COMLIB = $(OCGDIR)/blender/blenkernel/$(DEBUG_DIR)libblenkernel.a
-COMLIB += $(NAN_DECIMATION)/lib/libdecimation.a
COMLIB += $(OCGDIR)/blender/blenloader/$(DEBUG_DIR)libblenloader.a
COMLIB += $(OCGDIR)/blender/blenpluginapi/$(DEBUG_DIR)libblenpluginapi.a
COMLIB += $(OCGDIR)/blender/nodes_shd/$(DEBUG_DIR)libnodes_shd.a
@@ -100,13 +99,11 @@ COMLIB += $(OCGDIR)/blender/imbuf/$(DEBUG_DIR)libimbuf.a
COMLIB += $(OCGDIR)/blender/blenlib/$(DEBUG_DIR)libblenlib.a
COMLIB += $(NAN_IKSOLVER)/lib/libiksolver.a
COMLIB += $(NAN_MOTO)/lib/libmoto.a
-COMLIB += $(NAN_OPENNL)/lib/$(DEBUG_DIR)libopennl.a
COMLIB += $(NAN_SUPERLU)/lib/$(DEBUG_DIR)libsuperlu.a
COMLIB += $(OCGDIR)/blender/avi/$(DEBUG_DIR)libavi.a
COMLIB += $(NAN_JPEG)/lib/libjpeg.a
COMLIB += $(OCGDIR)/blender/gpu/$(DEBUG_DIR)libgpu.a
COMLIB += $(NAN_GLEW)/lib/libglew.a
-COMLIB += $(NAN_ELBEEM)/lib/$(DEBUG_DIR)libelbeem.a
COMLIB += $(OCGDIR)/blender/blenfont/$(DEBUG_DIR)libblenfont.a
ifneq ($(NAN_NO_KETSJI),true)
@@ -171,6 +168,10 @@ ifeq ($(WITH_OPENEXR), true)
COMLIB += $(OCGDIR)/blender/imbuf/openexr/$(DEBUG_DIR)libopenexr.a
endif
+ifeq ($(WITH_OPENJPEG), true)
+ COMLIB += $(OCGDIR)/extern/openjpeg/$(DEBUG_DIR)libopenjpeg.a
+endif
+
COMLIB += $(OCGDIR)/blender/imbuf/cineon/$(DEBUG_DIR)libcineon.a
ifeq ($(WITH_DDS), true)
@@ -220,6 +221,7 @@ endif
# note: space_api.a in begin of editors, screen.a in end
PULIB = $(NAN_MOTO)/lib/libmoto.a
+PULIB += $(NAN_DECIMATION)/lib/libdecimation.a
PULIB += $(OCGDIR)/blender/readblenfile/$(DEBUG_DIR)libreadblenfile.a
PULIB += $(OCGDIR)/blender/ed_space/libed_space.a
PULIB += $(OCGDIR)/blender/ed_sound/libed_sound.a
@@ -256,6 +258,8 @@ PULIB += $(OCGDIR)/blender/python/$(DEBUG_DIR)libpython.a
PULIB += $(OCGDIR)/blender/makesrna/$(DEBUG_DIR)librna.a
# note, no idea but it suddenly doesn't compile :(
PULIB += $(OCGDIR)/blender/blenlib/$(DEBUG_DIR)libblenlib.a
+PULIB += $(NAN_OPENNL)/lib/$(DEBUG_DIR)libopennl.a
+PULIB += $(NAN_ELBEEM)/lib/$(DEBUG_DIR)libelbeem.a
ifeq ($(NAN_NO_KETSJI),true)
PULIB += $(NAN_MOTO)/lib/libmoto.a
diff --git a/source/blender/Makefile b/source/blender/Makefile
index 3b092b6f3db..a12b53e6153 100644
--- a/source/blender/Makefile
+++ b/source/blender/Makefile
@@ -44,6 +44,11 @@ ifeq ($(WITH_QUICKTIME), true)
DIRS += quicktime
endif
+ifeq ($(WITH_OPENJPEG), true)
+ CFLAGS += -DWITH_OPENJPEG -I../../../../extern/libopenjpeg
+endif
+
+
DIR = $(OCGDIR)/blender
SOURCEDIR = source/blender
TESTDIRS = deflate streamglue
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 7d0c5b83e6e..7b7de08bd56 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -406,6 +406,10 @@ struct TexResult;
#define TEX_NODE_TRANSLATE 116
#define TEX_NODE_COORD 117
#define TEX_NODE_DISTANCE 118
+#define TEX_NODE_COMPOSE 119
+#define TEX_NODE_DECOMPOSE 120
+#define TEX_NODE_VALTONOR 121
+#define TEX_NODE_SCALE 122
/* 201-299 reserved. Use like this: TEX_NODE_PROC + TEX_CLOUDS, etc */
#define TEX_NODE_PROC 200
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 46153b928aa..5a612df2589 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -42,6 +42,10 @@ IF(WITH_OPENEXR)
ADD_DEFINITIONS(-DWITH_OPENEXR)
ENDIF(WITH_OPENEXR)
+IF(WITH_OPENJPEG)
+ ADD_DEFINITIONS(-DWITH_OPENJPEG)
+ENDIF(WITH_OPENJPEG)
+
IF(WITH_DDS)
ADD_DEFINITIONS(-DWITH_DDS)
ENDIF(WITH_DDS)
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index 25673aa6782..1ea9cfae78e 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -28,6 +28,8 @@ if env['WITH_BF_QUICKTIME']:
if env['WITH_BF_SDL']:
incs += ' ' + env['BF_SDL_INC']
+else:
+ defs += ' DISABLE_SDL'
if env['WITH_BF_INTERNATIONAL']:
defs += ' WITH_FREETYPE2'
diff --git a/source/blender/blenkernel/intern/Makefile b/source/blender/blenkernel/intern/Makefile
index acb1fd2deb6..6554c93662d 100644
--- a/source/blender/blenkernel/intern/Makefile
+++ b/source/blender/blenkernel/intern/Makefile
@@ -105,6 +105,10 @@ ifeq ($(WITH_DDS), true)
CPPFLAGS += -DWITH_DDS
endif
+ifeq ($(WITH_OPENJPEG), true)
+ CPPFLAGS += -DWITH_OPENJPEG
+endif
+
ifeq ($(WITH_QUICKTIME), true)
CPPFLAGS += -I../../quicktime
CPPFLAGS += -DWITH_QUICKTIME
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 62c9699aaf9..7ed87e734d6 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -6377,20 +6377,11 @@ static DerivedMesh * particleInstanceModifier_applyModifier(
psys->lattice=psys_get_lattice(md->scene, ob, psys);
if(psys->flag & (PSYS_HAIR_DONE|PSYS_KEYED)){
- float co[3];
- for(i=0; i< totvert; i++){
- dm->getVertCo(dm,i,co);
- if(i==0){
- min_co=max_co=co[track];
- }
- else{
- if(co[track]<min_co)
- min_co=co[track];
- if(co[track]>max_co)
- max_co=co[track];
- }
- }
+ float min_r[3], max_r[3];
+ dm->getMinMax(dm, min_r, max_r);
+ min_co=min_r[track];
+ max_co=max_r[track];
}
result = CDDM_from_template(dm, maxvert,dm->getNumEdges(dm)*totpart,maxface);
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 1e0abac915b..1acad4e9e86 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1999,19 +1999,23 @@ static bNodeThreadStack *ntreeGetThreadStack(bNodeTree *ntree, int thread)
{
ListBase *lb= &ntree->threadstack[thread];
bNodeThreadStack *nts;
-
+
+ /* for material shading this is called quite a lot (perhaps too much locking unlocking)
+ * however without locking we get bug #18058 - Campbell */
+ BLI_lock_thread(LOCK_CUSTOM1);
+
for(nts=lb->first; nts; nts=nts->next) {
if(!nts->used) {
nts->used= 1;
+ BLI_unlock_thread(LOCK_CUSTOM1);
return nts;
}
}
-
nts= MEM_callocN(sizeof(bNodeThreadStack), "bNodeThreadStack");
nts->stack= MEM_dupallocN(ntree->stack);
nts->used= 1;
BLI_addtail(lb, nts);
-
+ BLI_unlock_thread(LOCK_CUSTOM1);
return nts;
}
@@ -3003,12 +3007,15 @@ static void registerTextureNodes(ListBase *ntypelist)
nodeRegisterType(ntypelist, &tex_node_mix_rgb);
nodeRegisterType(ntypelist, &tex_node_valtorgb);
nodeRegisterType(ntypelist, &tex_node_rgbtobw);
+ nodeRegisterType(ntypelist, &tex_node_valtonor);
nodeRegisterType(ntypelist, &tex_node_curve_rgb);
nodeRegisterType(ntypelist, &tex_node_curve_time);
nodeRegisterType(ntypelist, &tex_node_invert);
nodeRegisterType(ntypelist, &tex_node_hue_sat);
nodeRegisterType(ntypelist, &tex_node_coord);
nodeRegisterType(ntypelist, &tex_node_distance);
+ nodeRegisterType(ntypelist, &tex_node_compose);
+ nodeRegisterType(ntypelist, &tex_node_decompose);
nodeRegisterType(ntypelist, &tex_node_output);
nodeRegisterType(ntypelist, &tex_node_viewer);
@@ -3020,6 +3027,7 @@ static void registerTextureNodes(ListBase *ntypelist)
nodeRegisterType(ntypelist, &tex_node_rotate);
nodeRegisterType(ntypelist, &tex_node_translate);
+ nodeRegisterType(ntypelist, &tex_node_scale);
nodeRegisterType(ntypelist, &tex_node_proc_voronoi);
nodeRegisterType(ntypelist, &tex_node_proc_blend);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 949808b2e56..249f67367f4 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -514,6 +514,7 @@ void unlink_object(Scene *scene, Object *ob)
while(sce) {
if(sce->id.lib==NULL) {
if(sce->camera==ob) sce->camera= NULL;
+ if(sce->toolsettings->skgen_template==ob) sce->toolsettings->skgen_template = NULL;
}
sce= sce->id.next;
}
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index afb4fb68c8c..2b484b84060 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -4387,7 +4387,7 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys,
gzf = gzopen(filename, "rb");
if (!gzf) {
snprintf(debugStrBuffer,256,"readFsPartData::error - Unable to open file for reading '%s' \n", filename);
- elbeemDebugOut(debugStrBuffer);
+ // XXX bad level call elbeemDebugOut(debugStrBuffer);
return;
}
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 11f8dfdf330..9ea115903b0 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -926,18 +926,18 @@ static void free_gammacross(Sequence * seq)
static void do_gammacross_effect_byte(float facf0, float facf1,
int x, int y,
- char *rect1,
- char *rect2,
- char *out)
+ unsigned char *rect1,
+ unsigned char *rect2,
+ unsigned char *out)
{
int fac1, fac2, col;
int xo;
- char *rt1, *rt2, *rt;
+ unsigned char *rt1, *rt2, *rt;
xo= x;
- rt1= (signed char *)rect1;
- rt2= (signed char *)rect2;
- rt= (signed char *)out;
+ rt1= (unsigned char *)rect1;
+ rt2= (unsigned char *)rect2;
+ rt= (unsigned char *)out;
fac2= (int)(256.0*facf0);
fac1= 256-fac2;
@@ -1996,6 +1996,9 @@ static void do_transform(Sequence * seq,float facf0, int x, int y,
float xs,ys,factxScale,factyScale,tx,ty,rad,s,c,xaux,yaux,factRot,px,py;
TransformVars *scale;
+ struct RenderData *rd = NULL; // XXX 2.5 global: &G.scene->r;
+
+
scale = (TransformVars *)seq->effectdata;
xo = x;
yo = y;
@@ -2006,8 +2009,10 @@ static void do_transform(Sequence * seq,float facf0, int x, int y,
//Factor translate
if(!scale->percent){
- tx = scale->xIni+(xo / 2.0f) + (scale->xFin-(xo / 2.0f) - scale->xIni+(xo / 2.0f)) * facf0;
- ty = scale->yIni+(yo / 2.0f) + (scale->yFin-(yo / 2.0f) - scale->yIni+(yo / 2.0f)) * facf0;
+ float rd_s = 0.0f; // XXX 2.5 global: (rd->size / 100.0f);
+
+ tx = scale->xIni * rd_s+(xo / 2.0f) + (scale->xFin * rd_s -(xo / 2.0f) - scale->xIni * rd_s +(xo / 2.0f)) * facf0;
+ ty = scale->yIni * rd_s+(yo / 2.0f) + (scale->yFin * rd_s -(yo / 2.0f) - scale->yIni * rd_s +(yo / 2.0f)) * facf0;
}else{
tx = xo*(scale->xIni/100.0f)+(xo / 2.0f) + (xo*(scale->xFin/100.0f)-(xo / 2.0f) - xo*(scale->xIni/100.0f)+(xo / 2.0f)) * facf0;
ty = yo*(scale->yIni/100.0f)+(yo / 2.0f) + (yo*(scale->yFin/100.0f)-(yo / 2.0f) - yo*(scale->yIni/100.0f)+(yo / 2.0f)) * facf0;
@@ -2019,6 +2024,7 @@ static void do_transform(Sequence * seq,float facf0, int x, int y,
s= sin(rad);
c= cos(rad);
+
for (yi = 0; yi < yo; yi++) {
for (xi = 0; xi < xo; xi++) {
//tranlate point
diff --git a/source/blender/blenkernel/intern/sequence.c b/source/blender/blenkernel/intern/sequence.c
index b32f1c765af..121dfce4980 100644
--- a/source/blender/blenkernel/intern/sequence.c
+++ b/source/blender/blenkernel/intern/sequence.c
@@ -2192,6 +2192,14 @@ static TStripElem* do_build_seq_recursively(Scene *scene, Sequence * seq, int cf
}
}
+/* Bug: 18209
+ * when dragging the mouse over a metastrip, on mouse-up for some unknown
+ * reason in some cases the metastrips TStripElem->ibuf->rect is NULL,
+ * This should be fixed but I had a look and couldnt work out why its
+ * happening so for now workaround with a NULL check - campbell */
+
+#define SEQ_SPECIAL_SEQ_UPDATE_WORKAROUND
+
static TStripElem* do_build_seq_array_recursively(Scene *scene,
ListBase *seqbasep, int cfra, int chanshown)
{
@@ -2360,7 +2368,14 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene,
!se2->ibuf_comp->rect_float) {
IMB_rect_from_float(se2->ibuf);
}
-
+
+#ifdef SEQ_SPECIAL_SEQ_UPDATE_WORKAROUND
+ if (se2->ibuf->rect==NULL && se2->ibuf->rect_float==NULL) {
+ printf("ERROR: sequencer se2->ibuf missing buffer\n");
+ } else if (se1->ibuf && se1->ibuf->rect==NULL && se1->ibuf->rect_float==NULL) {
+ printf("ERROR: sequencer se1->ibuf missing buffer\n");
+ } else {
+#endif
/* bad hack, to fix crazy input ordering of
those two effects */
@@ -2382,6 +2397,10 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene,
se2->ibuf_comp);
}
+#ifdef SEQ_SPECIAL_SEQ_UPDATE_WORKAROUND
+ }
+#endif
+
IMB_cache_limiter_insert(se2->ibuf_comp);
IMB_cache_limiter_ref(se2->ibuf_comp);
IMB_cache_limiter_touch(se2->ibuf_comp);
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 70a2e9ca3a3..d7accd54fb9 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -1559,7 +1559,7 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
/* note we don't use sb->mediafrict but use sb->aeroedge for magnitude of effect*/
if(sb->aeroedge){
float vel[3],sp[3],pr[3],force[3];
- float f,windfactor = 250.0f;
+ float f,windfactor = 0.25f;
/*see if we have wind*/
if(do_effector) {
float speed[3]={0.0f,0.0f,0.0f};
@@ -2392,7 +2392,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
BodyPoint *bproot;
ListBase *do_effector;
float iks, gravity;
- float fieldfactor = 1000.0f, windfactor = 250.0f;
+ float fieldfactor = -1.0f, windfactor = 0.25;
int do_deflector,do_selfcollision,do_springcollision,do_aero;
gravity = sb->grav * sb_grav_force_scale(ob);
@@ -2454,7 +2454,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
BodySpring *bs;
ListBase *do_effector;
float iks, ks, kd, gravity;
- float fieldfactor = 1000.0f, windfactor = 250.0f;
+ float fieldfactor = -1.0f, windfactor = 0.25f;
float tune = sb->ballstiff;
int a, b, do_deflector,do_selfcollision,do_springcollision,do_aero;
diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h
index 5acee360872..30bb4d11450 100644
--- a/source/blender/blenlib/BLI_arithb.h
+++ b/source/blender/blenlib/BLI_arithb.h
@@ -392,8 +392,10 @@ void tubemap(float x, float y, float z, float *u, float *v);
void spheremap(float x, float y, float z, float *u, float *v);
int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float i1[3], float i2[3]);
+int LineIntersectLineStrict(float v1[3], float v2[3], float v3[3], float v4[3], float vi[3], float *lambda);
int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
int RayIntersectsTriangle(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
+int RayIntersectsTriangleThreshold(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv, float threshold);
int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint);
int AxialLineIntersectsTriangle(int axis, float co1[3], float co2[3], float v0[3], float v1[3], float v2[3], float *lambda);
int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3]);
diff --git a/source/blender/blenlib/BLI_graph.h b/source/blender/blenlib/BLI_graph.h
index 160c2e04cf5..f4fccfcbb2c 100644
--- a/source/blender/blenlib/BLI_graph.h
+++ b/source/blender/blenlib/BLI_graph.h
@@ -60,6 +60,39 @@ typedef struct BArc {
int symmetry_flag;
} BArc;
+struct BArcIterator;
+
+void* IT_head(void* iter);
+void* IT_tail(void* iter);
+void* IT_peek(void* iter, int n);
+void* IT_next(void* iter);
+void* IT_nextN(void* iter, int n);
+void* IT_previous(void* iter);
+int IT_stopped(void* iter);
+
+typedef void* (*HeadFct)(void* iter);
+typedef void* (*TailFct)(void* iter);
+typedef void* (*PeekFct)(void* iter, int n);
+typedef void* (*NextFct)(void* iter);
+typedef void* (*NextNFct)(void* iter, int n);
+typedef void* (*PreviousFct)(void* iter);
+typedef int (*StoppedFct)(void* iter);
+
+typedef struct BArcIterator {
+ HeadFct head;
+ TailFct tail;
+ PeekFct peek;
+ NextFct next;
+ NextNFct nextN;
+ PreviousFct previous;
+ StoppedFct stopped;
+
+ float *p, *no;
+
+ int length;
+ int index;
+} BArcIterator;
+
/* Helper structure for radial symmetry */
typedef struct RadialArc
{
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index 0df4792cd3d..2368f0cd2ba 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -3896,6 +3896,57 @@ int RayIntersectsTriangle(float p1[3], float d[3], float v0[3], float v1[3], flo
return 1;
}
+int RayIntersectsTriangleThreshold(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv, float threshold)
+{
+ float p[3], s[3], e1[3], e2[3], q[3];
+ float a, f, u, v;
+ float du = 0, dv = 0;
+
+ VecSubf(e1, v1, v0);
+ VecSubf(e2, v2, v0);
+
+ Crossf(p, d, e2);
+ a = Inpf(e1, p);
+ if ((a > -0.000001) && (a < 0.000001)) return 0;
+ f = 1.0f/a;
+
+ VecSubf(s, p1, v0);
+
+ Crossf(q, s, e1);
+ *lambda = f * Inpf(e2, q);
+ if ((*lambda < 0.0)) return 0;
+
+ u = f * Inpf(s, p);
+ v = f * Inpf(d, q);
+
+ if (u < 0) du = u;
+ if (u > 1) du = u - 1;
+ if (v < 0) dv = v;
+ if (v > 1) dv = v - 1;
+ if (u > 0 && v > 0 && u + v > 1)
+ {
+ float t = u + v - 1;
+ du = u - t/2;
+ dv = v - t/2;
+ }
+
+ VecMulf(e1, du);
+ VecMulf(e2, dv);
+
+ if (Inpf(e1, e1) + Inpf(e2, e2) > threshold * threshold)
+ {
+ return 0;
+ }
+
+ if(uv) {
+ uv[0]= u;
+ uv[1]= v;
+ }
+
+ return 1;
+}
+
+
/* Adapted from the paper by Kasper Fauerby */
/* "Improved Collision detection and Response" */
static int getLowestRoot(float a, float b, float c, float maxR, float* root)
@@ -4245,6 +4296,67 @@ int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float
}
}
+/* Intersection point strictly between the two lines
+ * 0 when no intersection is found
+ * */
+int LineIntersectLineStrict(float v1[3], float v2[3], float v3[3], float v4[3], float vi[3], float *lambda)
+{
+ float a[3], b[3], c[3], ab[3], cb[3], ca[3], dir1[3], dir2[3];
+ float d;
+ float d1;
+
+ VecSubf(c, v3, v1);
+ VecSubf(a, v2, v1);
+ VecSubf(b, v4, v3);
+
+ VecCopyf(dir1, a);
+ Normalize(dir1);
+ VecCopyf(dir2, b);
+ Normalize(dir2);
+ d = Inpf(dir1, dir2);
+ if (d == 1.0f || d == -1.0f || d == 0) {
+ /* colinear or one vector is zero-length*/
+ return 0;
+ }
+
+ d1 = d;
+
+ Crossf(ab, a, b);
+ d = Inpf(c, ab);
+
+ /* test if the two lines are coplanar */
+ if (d > -0.000001f && d < 0.000001f) {
+ float f1, f2;
+ Crossf(cb, c, b);
+ Crossf(ca, c, a);
+
+ f1 = Inpf(cb, ab) / Inpf(ab, ab);
+ f2 = Inpf(ca, ab) / Inpf(ab, ab);
+
+ if (f1 >= 0 && f1 <= 1 &&
+ f2 >= 0 && f2 <= 1)
+ {
+ VecMulf(a, f1);
+ VecAddf(vi, v1, a);
+
+ if (lambda != NULL)
+ {
+ *lambda = f1;
+ }
+
+ return 1; /* intersection found */
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+}
+
int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3])
{
return (min1[0]<max2[0] && min1[1]<max2[1] && min1[2]<max2[2] &&
diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c
index f1057ff3efe..85a95fa6e66 100644
--- a/source/blender/blenlib/intern/bpath.c
+++ b/source/blender/blenlib/intern/bpath.c
@@ -341,9 +341,9 @@ void BLI_bpathIterator_step( struct BPathIterator *bpi) {
bSound *snd = (bSound *)bpi->data;
bpi->lib = snd->id.lib ? snd->id.lib->filename : NULL;
- bpi->path = snd->sample->name;
+ bpi->path = snd->name;
bpi->name = snd->id.name+2;
- bpi->len = sizeof(snd->sample->name);
+ bpi->len = sizeof(snd->name);
/* we are done, advancing to the next item, this type worked fine */
break;
diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c
index 11bb8ea8964..cc15c499290 100644
--- a/source/blender/blenlib/intern/graph.c
+++ b/source/blender/blenlib/intern/graph.c
@@ -1031,6 +1031,11 @@ void BLI_markdownSymmetry(BGraph *graph, BNode *root_node, float limit)
BNode *node;
BArc *arc;
+ if (root_node == NULL)
+ {
+ return;
+ }
+
if (BLI_isGraphCyclic(graph))
{
return;
@@ -1083,3 +1088,56 @@ void BLI_markdownSymmetry(BGraph *graph, BNode *root_node, float limit)
}
}
+void* IT_head(void* arg)
+{
+ BArcIterator *iter = (BArcIterator*)arg;
+ return iter->head(iter);
+}
+
+void* IT_tail(void* arg)
+{
+ BArcIterator *iter = (BArcIterator*)arg;
+ return iter->tail(iter);
+}
+
+void* IT_peek(void* arg, int n)
+{
+ BArcIterator *iter = (BArcIterator*)arg;
+
+ if (iter->index + n < 0)
+ {
+ return iter->head(iter);
+ }
+ else if (iter->index + n >= iter->length)
+ {
+ return iter->tail(iter);
+ }
+ else
+ {
+ return iter->peek(iter, n);
+ }
+}
+
+void* IT_next(void* arg)
+{
+ BArcIterator *iter = (BArcIterator*)arg;
+ return iter->next(iter);
+}
+
+void* IT_nextN(void* arg, int n)
+{
+ BArcIterator *iter = (BArcIterator*)arg;
+ return iter->nextN(iter, n);
+}
+
+void* IT_previous(void* arg)
+{
+ BArcIterator *iter = (BArcIterator*)arg;
+ return iter->previous(iter);
+}
+
+int IT_stopped(void* arg)
+{
+ BArcIterator *iter = (BArcIterator*)arg;
+ return iter->stopped(iter);
+}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index c2fd08bd20f..d64abd99d9c 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3758,6 +3758,8 @@ static void lib_link_scene(FileData *fd, Main *main)
sce->toolsettings->sculpt->brush=
newlibadr_us(fd, sce->id.lib, sce->toolsettings->sculpt->brush);
+ sce->toolsettings->skgen_template = newlibadr(fd, sce->id.lib, sce->toolsettings->skgen_template);
+
for(base= sce->base.first; base; base= next) {
next= base->next;
@@ -8092,28 +8094,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
ima->flag |= IMA_DO_PREMUL;
}
}
-
- if (main->versionfile < 245 || main->subversionfile < 12)
- {
- /* initialize skeleton generation toolsettings */
- for(sce=main->scene.first; sce; sce = sce->id.next)
- {
- sce->toolsettings->skgen_resolution = 50;
- sce->toolsettings->skgen_threshold_internal = 0.01f;
- sce->toolsettings->skgen_threshold_external = 0.01f;
- sce->toolsettings->skgen_angle_limit = 45.0f;
- sce->toolsettings->skgen_length_ratio = 1.3f;
- sce->toolsettings->skgen_length_limit = 1.5f;
- sce->toolsettings->skgen_correlation_limit = 0.98f;
- sce->toolsettings->skgen_symmetry_limit = 0.1f;
- sce->toolsettings->skgen_postpro = SKGEN_SMOOTH;
- sce->toolsettings->skgen_postpro_passes = 1;
- sce->toolsettings->skgen_options = SKGEN_FILTER_INTERNAL|SKGEN_FILTER_EXTERNAL|SKGEN_SUB_CORRELATION;
- sce->toolsettings->skgen_subdivisions[0] = SKGEN_SUB_CORRELATION;
- sce->toolsettings->skgen_subdivisions[1] = SKGEN_SUB_LENGTH;
- sce->toolsettings->skgen_subdivisions[2] = SKGEN_SUB_ANGLE;
- }
- }
}
/* sanity check for skgen
@@ -8714,6 +8694,31 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for (sce= main->scene.first; sce; sce= sce->id.next) {
sce->toolsettings->imapaint.seam_bleed = 2;
sce->toolsettings->imapaint.normal_angle = 80;
+
+ /* initialize skeleton generation toolsettings */
+ sce->toolsettings->skgen_resolution = 250;
+ sce->toolsettings->skgen_threshold_internal = 0.1f;
+ sce->toolsettings->skgen_threshold_external = 0.1f;
+ sce->toolsettings->skgen_angle_limit = 30.0f;
+ sce->toolsettings->skgen_length_ratio = 1.3f;
+ sce->toolsettings->skgen_length_limit = 1.5f;
+ sce->toolsettings->skgen_correlation_limit = 0.98f;
+ sce->toolsettings->skgen_symmetry_limit = 0.1f;
+ sce->toolsettings->skgen_postpro = SKGEN_SMOOTH;
+ sce->toolsettings->skgen_postpro_passes = 3;
+ sce->toolsettings->skgen_options = SKGEN_FILTER_INTERNAL|SKGEN_FILTER_EXTERNAL|SKGEN_FILTER_SMART|SKGEN_SUB_CORRELATION|SKGEN_HARMONIC;
+ sce->toolsettings->skgen_subdivisions[0] = SKGEN_SUB_CORRELATION;
+ sce->toolsettings->skgen_subdivisions[1] = SKGEN_SUB_LENGTH;
+ sce->toolsettings->skgen_subdivisions[2] = SKGEN_SUB_ANGLE;
+
+
+ sce->toolsettings->skgen_retarget_angle_weight = 1.0f;
+ sce->toolsettings->skgen_retarget_length_weight = 1.0f;
+ sce->toolsettings->skgen_retarget_distance_weight = 1.0f;
+
+ /* Skeleton Sketching */
+ sce->toolsettings->bone_sketching = 0;
+ sce->toolsettings->skgen_retarget_roll = SK_RETARGET_ROLL_VIEW;
}
}
if (main->versionfile < 248 || (main->versionfile == 248 && main->subversionfile < 3)) {
@@ -9734,6 +9739,9 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
expand_animdata(fd, mainvar, sce->adt);
expand_keyingsets(fd, mainvar, &sce->keyingsets);
+ if(sce->set)
+ expand_doit(fd, mainvar, sce->set);
+
if(sce->nodetree)
expand_nodetree(fd, mainvar, sce->nodetree);
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 2adce78c222..f898a363da7 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -2152,7 +2152,7 @@ static void write_global(WriteData *wd, Main *mainvar)
fg.subversion= BLENDER_SUBVERSION;
fg.minversion= BLENDER_MINVERSION;
fg.minsubversion= BLENDER_MINSUBVERSION;
-
+ fg.pads= 0; /* prevent mem checkers from complaining */
writestruct(wd, GLOB, "FileGlobal", 1, &fg);
}
diff --git a/source/blender/blenpluginapi/iff.h b/source/blender/blenpluginapi/iff.h
index e7f328d870f..9378cdc9134 100644
--- a/source/blender/blenpluginapi/iff.h
+++ b/source/blender/blenpluginapi/iff.h
@@ -45,6 +45,8 @@
#define IB_zbuf (1 << 13)
#define IB_rgba (1 << 14)
+#define JP2 (1 << 18)
+
#define AMI (1 << 31)
#define PNG (1 << 30)
#define Anim (1 << 29)
@@ -56,10 +58,6 @@
#endif
#define RADHDR (1<<24)
-#ifdef WITH_OPENJPEG
-#define JP2 (1 << 18)
-#endif
-
#define RAWTGA (TGA | 1)
#define JPG_STD (JPG | (0 << 8))
diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt
index b014454d252..06b0fb4ab41 100644
--- a/source/blender/editors/CMakeLists.txt
+++ b/source/blender/editors/CMakeLists.txt
@@ -52,6 +52,10 @@ IF(WITH_OPENEXR)
ADD_DEFINITIONS(-DWITH_OPENEXR)
ENDIF(WITH_OPENEXR)
+IF(WITH_OPENJPEG)
+ ADD_DEFINITIONS(-DWITH_OPENJPEG)
+ENDIF(WITH_OPENJPEG)
+
IF(WITH_QUICKTIME)
SET(INC ${INC} ${QUICKTIME_INC})
ADD_DEFINITIONS(-DWITH_QUICKTIME)
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index 9f50bb3f044..06b6efab94b 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -31,7 +31,7 @@
/* internal exports only */
struct wmOperatorType;
-/* editarmature.c */
+/* editarmature.c operators */
void ARMATURE_OT_bone_primitive_add(struct wmOperatorType *ot);
void ARMATURE_OT_align_bones(struct wmOperatorType *ot);
void ARMATURE_OT_calculate_roll(struct wmOperatorType *ot);
@@ -61,5 +61,24 @@ void POSE_OT_select_parent(struct wmOperatorType *ot);
void POSE_OT_select_hierarchy(struct wmOperatorType *ot);
void POSE_OT_select_connected(struct wmOperatorType *ot);
+/* editarmature.c */
+struct bArmature;
+struct EditBone;
+
+struct EditBone *addEditBone(struct bArmature *arm, char *name);
+
+/* duplicate method */
+void preEditBoneDuplicate(struct ListBase *editbones);
+struct EditBone *duplicateEditBone(struct EditBone *curBone, char *name, struct ListBase *editbones, struct Object *ob);
+void updateDuplicateSubtarget(struct EditBone *dupBone, struct ListBase *editbones, struct Object *ob);
+
+/* duplicate method (cross objects */
+
+/* editbones is the target list */
+struct EditBone *duplicateEditBoneObjects(struct EditBone *curBone, char *name, struct ListBase *editbones, struct Object *src_ob, struct Object *dst_ob);
+
+/* editbones is the source list */
+void updateDuplicateSubtargetObjects(struct EditBone *dupBone, struct ListBase *editbones, struct Object *src_ob, struct Object *dst_ob);
+
#endif /* ED_ARMATURE_INTERN_H */
diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c
index 021f87ea663..2aed96b61c5 100644
--- a/source/blender/editors/armature/editarmature.c
+++ b/source/blender/editors/armature/editarmature.c
@@ -75,6 +75,7 @@
#include "BIF_gl.h"
#include "BIF_transform.h"
+// XXX etch-a-ton #include "BIF_generate.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -463,13 +464,16 @@ static EditBone *editbone_name_exists (ListBase *edbo, char *name)
}
/* note: there's a unique_bone_name() too! */
-void unique_editbone_name (ListBase *edbo, char *name)
+void unique_editbone_name (ListBase *edbo, char *name, EditBone *bone)
{
+ EditBone *dupli;
char tempname[64];
int number;
char *dot;
+
+ dupli = editbone_name_exists(edbo, name);
- if (editbone_name_exists(edbo, name)) {
+ if (dupli && bone != dupli) {
/* Strip off the suffix, if it's a number */
number= strlen(name);
if (number && isdigit(name[number-1])) {
@@ -717,7 +721,7 @@ int join_armature(Scene *scene, View3D *v3d)
curbone= editbone_name_exists(curarm->edbo, pchan->name);
/* Get new name */
- unique_editbone_name(arm->edbo, curbone->name);
+ unique_editbone_name(arm->edbo, curbone->name, NULL);
/* Transform the bone */
{
@@ -1851,6 +1855,8 @@ void ED_armature_to_edit(Object *ob)
ED_armature_edit_free(ob);
arm->edbo= MEM_callocN(sizeof(ListBase), "edbo armature");
make_boneList(arm->edbo, &arm->bonebase,NULL);
+
+ // XXX etch-a-ton BIF_freeTemplates(); /* force template update when entering editmode */
}
@@ -2085,14 +2091,12 @@ void undo_push_armature(bContext *C, char *name)
/* *************** Adding stuff in editmode *************** */
/* default bone add, returns it selected, but without tail set */
-static EditBone *add_editbone(Object *obedit, char *name)
+EditBone *addEditBone(bArmature *arm, char *name)
{
- bArmature *arm= obedit->data;
-
EditBone *bone= MEM_callocN(sizeof(EditBone), "eBone");
BLI_strncpy(bone->name, name, 32);
- unique_editbone_name(arm->edbo, bone->name);
+ unique_editbone_name(arm->edbo, bone->name, NULL);
BLI_addtail(arm->edbo, bone);
@@ -2111,6 +2115,14 @@ static EditBone *add_editbone(Object *obedit, char *name)
return bone;
}
+/* default bone add, returns it selected, but without tail set */
+static EditBone *add_editbone(Object *obedit, char *name)
+{
+ bArmature *arm= obedit->data;
+
+ return addEditBone(arm, name);
+}
+
/* v3d and rv3d are allowed to be NULL */
void add_primitive_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
@@ -2341,19 +2353,35 @@ static EditBone *get_named_editbone(ListBase *edbo, char *name)
return NULL;
}
-static void update_dup_subtarget(Object *obedit, EditBone *dupBone)
+/* Call this before doing any duplications
+ * */
+void preEditBoneDuplicate(ListBase *editbones)
+{
+ EditBone *eBone;
+
+ /* clear temp */
+ for (eBone = editbones->first; eBone; eBone = eBone->next)
+ {
+ eBone->temp = NULL;
+ }
+}
+
+/*
+ * Note: When duplicating cross objects, editbones here is the list of bones
+ * from the SOURCE object but ob is the DESTINATION object
+ * */
+void updateDuplicateSubtargetObjects(EditBone *dupBone, ListBase *editbones, Object *src_ob, Object *dst_ob)
{
/* If an edit bone has been duplicated, lets
* update it's constraints if the subtarget
* they point to has also been duplicated
*/
- bArmature *arm = obedit->data;
EditBone *oldtarget, *newtarget;
bPoseChannel *chan;
bConstraint *curcon;
ListBase *conlist;
- if ( (chan = verify_pose_channel(obedit->pose, dupBone->name)) ) {
+ if ( (chan = verify_pose_channel(dst_ob->pose, dupBone->name)) ) {
if ( (conlist = &chan->constraints) ) {
for (curcon = conlist->first; curcon; curcon=curcon->next) {
/* does this constraint have a subtarget in
@@ -2367,14 +2395,15 @@ static void update_dup_subtarget(Object *obedit, EditBone *dupBone)
cti->get_constraint_targets(curcon, &targets);
for (ct= targets.first; ct; ct= ct->next) {
- if ((ct->tar == obedit) && (ct->subtarget[0])) {
- oldtarget = get_named_editbone(arm->edbo, ct->subtarget);
+ if ((ct->tar == src_ob) && (ct->subtarget[0])) {
+ ct->tar = dst_ob; /* update target */
+ oldtarget = get_named_editbone(editbones, ct->subtarget);
if (oldtarget) {
/* was the subtarget bone duplicated too? If
* so, update the constraint to point at the
* duplicate of the old subtarget.
*/
- if (oldtarget->flag & BONE_SELECTED){
+ if (oldtarget->temp) {
newtarget = (EditBone *) oldtarget->temp;
strcpy(ct->subtarget, newtarget->name);
}
@@ -2390,6 +2419,79 @@ static void update_dup_subtarget(Object *obedit, EditBone *dupBone)
}
}
+void updateDuplicateSubtarget(EditBone *dupBone, ListBase *editbones, Object *ob)
+{
+ updateDuplicateSubtargetObjects(dupBone, editbones, ob, ob);
+}
+
+
+EditBone *duplicateEditBoneObjects(EditBone *curBone, char *name, ListBase *editbones, Object *src_ob, Object *dst_ob)
+{
+ EditBone *eBone = MEM_callocN(sizeof(EditBone), "addup_editbone");
+
+ /* Copy data from old bone to new bone */
+ memcpy(eBone, curBone, sizeof(EditBone));
+
+ curBone->temp = eBone;
+ eBone->temp = curBone;
+
+ if (name != NULL)
+ {
+ BLI_strncpy(eBone->name, name, 32);
+ }
+
+ unique_editbone_name(editbones, eBone->name, NULL);
+ BLI_addtail(editbones, eBone);
+
+ /* Lets duplicate the list of constraints that the
+ * current bone has.
+ */
+ if (src_ob->pose) {
+ bPoseChannel *chanold, *channew;
+ ListBase *listold, *listnew;
+
+ chanold = verify_pose_channel(src_ob->pose, curBone->name);
+ if (chanold) {
+ listold = &chanold->constraints;
+ if (listold) {
+ /* WARNING: this creates a new posechannel, but there will not be an attached bone
+ * yet as the new bones created here are still 'EditBones' not 'Bones'.
+ */
+ channew =
+ verify_pose_channel(dst_ob->pose, eBone->name);
+ if (channew) {
+ /* copy transform locks */
+ channew->protectflag = chanold->protectflag;
+
+ /* copy bone group */
+ channew->agrp_index= chanold->agrp_index;
+
+ /* ik (dof) settings */
+ channew->ikflag = chanold->ikflag;
+ VECCOPY(channew->limitmin, chanold->limitmin);
+ VECCOPY(channew->limitmax, chanold->limitmax);
+ VECCOPY(channew->stiffness, chanold->stiffness);
+ channew->ikstretch= chanold->ikstretch;
+
+ /* constraints */
+ listnew = &channew->constraints;
+ copy_constraints(listnew, listold);
+
+ /* custom shape */
+ channew->custom= chanold->custom;
+ }
+ }
+ }
+ }
+
+ return eBone;
+}
+
+EditBone *duplicateEditBone(EditBone *curBone, char *name, ListBase *editbones, Object *ob)
+{
+ return duplicateEditBoneObjects(curBone, name, editbones, ob, ob);
+}
+
/* previously adduplicate_armature */
static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
{
@@ -2407,6 +2509,8 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
armature_sync_selection(arm->edbo); // XXX why is this needed?
+ preEditBoneDuplicate(arm->edbo);
+
/* Select mirrored bones */
if (arm->flag & ARM_MIRROR_EDIT) {
for (curBone=arm->edbo->first; curBone; curBone=curBone->next) {
@@ -2419,6 +2523,7 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
}
}
}
+
/* Find the selected bones and duplicate them as needed */
for (curBone=arm->edbo->first; curBone && curBone!=firstDup; curBone=curBone->next) {
@@ -2433,7 +2538,7 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
curBone->temp = eBone;
eBone->temp = curBone;
- unique_editbone_name(arm->edbo, eBone->name);
+ unique_editbone_name(arm->edbo, eBone->name, NULL);
BLI_addtail(arm->edbo, eBone);
if (!firstDup)
firstDup=eBone;
@@ -2494,9 +2599,9 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
*/
eBone->parent = NULL;
}
- else if (curBone->parent->flag & BONE_SELECTED) {
- /* If this bone has a parent that IS selected,
- * Set the duplicate->parent to the curBone->parent->duplicate
+ else if (curBone->parent->temp) {
+ /* If this bone has a parent that was duplicated,
+ * Set the duplicate->parent to the curBone->parent->temp
*/
eBone->parent= (EditBone *)curBone->parent->temp;
}
@@ -2511,7 +2616,7 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
/* Lets try to fix any constraint subtargets that might
* have been duplicated
*/
- update_dup_subtarget(obedit, eBone);
+ updateDuplicateSubtarget(eBone, arm->edbo, obedit);
}
}
}
@@ -3122,7 +3227,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
else strcat(newbone->name, "_R");
}
}
- unique_editbone_name(arm->edbo, newbone->name);
+ unique_editbone_name(arm->edbo, newbone->name, NULL);
/* Add the new bone to the list */
BLI_addtail(arm->edbo, newbone);
@@ -3299,7 +3404,7 @@ static int armature_subdivide_exec(bContext *C, wmOperator *op)
newbone->flag |= BONE_CONNECTED;
- unique_editbone_name(arm->edbo, newbone->name);
+ unique_editbone_name(arm->edbo, newbone->name, NULL);
/* correct parent bones */
for (tbone = arm->edbo->first; tbone; tbone=tbone->next) {
@@ -5009,7 +5114,7 @@ void armature_bone_rename(Object *ob, char *oldnamep, char *newnamep)
eBone= editbone_name_exists(arm->edbo, oldname);
if (eBone) {
- unique_editbone_name(arm->edbo, newname);
+ unique_editbone_name(arm->edbo, newname, NULL);
BLI_strncpy(eBone->name, newname, MAXBONENAME);
}
else return;
@@ -5236,9 +5341,9 @@ EditBone * subdivideByAngle(Scene *scene, Object *obedit, ReebArc *arc, ReebNode
if (scene->toolsettings->skgen_options & SKGEN_CUT_ANGLE)
{
- ReebArcIterator iter;
- EmbedBucket *current = NULL;
- EmbedBucket *previous = NULL;
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
+ float *previous = NULL, *current = NULL;
EditBone *child = NULL;
EditBone *parent = NULL;
EditBone *root = NULL;
@@ -5250,22 +5355,28 @@ EditBone * subdivideByAngle(Scene *scene, Object *obedit, ReebArc *arc, ReebNode
root = parent;
- for (initArcIterator(&iter, arc, head), previous = nextBucket(&iter), current = nextBucket(&iter);
- current;
- previous = current, current = nextBucket(&iter))
+ initArcIterator(iter, arc, head);
+ IT_next(iter);
+ previous = iter->p;
+
+ for (IT_next(iter);
+ IT_stopped(iter) == 0;
+ previous = iter->p, IT_next(iter))
{
float vec1[3], vec2[3];
float len1, len2;
+
+ current = iter->p;
- VecSubf(vec1, previous->p, parent->head);
- VecSubf(vec2, current->p, previous->p);
+ VecSubf(vec1, previous, parent->head);
+ VecSubf(vec2, current, previous);
len1 = Normalize(vec1);
len2 = Normalize(vec2);
if (len1 > 0.0f && len2 > 0.0f && Inpf(vec1, vec2) < angleLimit)
{
- VECCOPY(parent->tail, previous->p);
+ VECCOPY(parent->tail, previous);
child = add_editbone(obedit, "Bone");
VECCOPY(child->head, parent->tail);
@@ -5292,182 +5403,29 @@ EditBone * subdivideByAngle(Scene *scene, Object *obedit, ReebArc *arc, ReebNode
return lastBone;
}
-float calcVariance(ReebArc *arc, int start, int end, float v0[3], float n[3])
-{
- int len = 2 + abs(end - start);
-
- if (len > 2)
- {
- ReebArcIterator iter;
- EmbedBucket *bucket = NULL;
- float avg_t = 0.0f;
- float s_t = 0.0f;
- float s_xyz = 0.0f;
-
- /* First pass, calculate average */
- for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
- bucket;
- bucket = nextBucket(&iter))
- {
- float v[3];
-
- VecSubf(v, bucket->p, v0);
- avg_t += Inpf(v, n);
- }
-
- avg_t /= Inpf(n, n);
- avg_t += 1.0f; /* adding start (0) and end (1) values */
- avg_t /= len;
-
- /* Second pass, calculate s_xyz and s_t */
- for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
- bucket;
- bucket = nextBucket(&iter))
- {
- float v[3], d[3];
- float dt;
-
- VecSubf(v, bucket->p, v0);
- Projf(d, v, n);
- VecSubf(v, v, d);
-
- dt = VecLength(d) - avg_t;
-
- s_t += dt * dt;
- s_xyz += Inpf(v, v);
- }
-
- /* adding start(0) and end(1) values to s_t */
- s_t += (avg_t * avg_t) + (1 - avg_t) * (1 - avg_t);
-
- return s_xyz / s_t;
- }
- else
- {
- return 0;
- }
-}
-
-float calcDistance(ReebArc *arc, int start, int end, float head[3], float tail[3])
-{
- ReebArcIterator iter;
- EmbedBucket *bucket = NULL;
- float max_dist = 0;
-
- /* calculate maximum distance */
- for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
- bucket;
- bucket = nextBucket(&iter))
- {
- float v1[3], v2[3], c[3];
- float dist;
-
- VecSubf(v1, head, tail);
- VecSubf(v2, bucket->p, tail);
-
- Crossf(c, v1, v2);
-
- dist = Inpf(c, c) / Inpf(v1, v1);
-
- max_dist = dist > max_dist ? dist : max_dist;
- }
-
-
- return max_dist;
-}
-
-EditBone * subdivideByCorrelation(Scene *scene, Object *obedit, ReebArc *arc, ReebNode *head, ReebNode *tail)
+EditBone * test_subdivideByCorrelation(Scene *scene, Object *obedit, ReebArc *arc, ReebNode *head, ReebNode *tail)
{
- ReebArcIterator iter;
- float n[3];
- float ADAPTIVE_THRESHOLD = scene->toolsettings->skgen_correlation_limit;
EditBone *lastBone = NULL;
-
- /* init iterator to get start and end from head */
- initArcIterator(&iter, arc, head);
-
- /* Calculate overall */
- VecSubf(n, arc->buckets[iter.end].p, head->p);
-
+
if (scene->toolsettings->skgen_options & SKGEN_CUT_CORRELATION)
{
- EmbedBucket *bucket = NULL;
- EmbedBucket *previous = NULL;
- EditBone *child = NULL;
- EditBone *parent = NULL;
- float normal[3] = {0, 0, 0};
- float avg_normal[3];
- int total = 0;
- int boneStart = iter.start;
-
- parent = add_editbone(obedit, "Bone");
- parent->flag = BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
- VECCOPY(parent->head, head->p);
+ float invmat[4][4] = { {1, 0, 0, 0},
+ {0, 1, 0, 0},
+ {0, 0, 1, 0},
+ {0, 0, 0, 1}};
+ float tmat[3][3] = { {1, 0, 0},
+ {0, 1, 0},
+ {0, 0, 1}};
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
+ bArmature *arm= obedit->data;
- for (previous = nextBucket(&iter), bucket = nextBucket(&iter);
- bucket;
- previous = bucket, bucket = nextBucket(&iter))
- {
- float btail[3];
- float value = 0;
-
- if (scene->toolsettings->skgen_options & SKGEN_STICK_TO_EMBEDDING)
- {
- VECCOPY(btail, bucket->p);
- }
- else
- {
- float length;
-
- /* Calculate normal */
- VecSubf(n, bucket->p, parent->head);
- length = Normalize(n);
-
- total += 1;
- VecAddf(normal, normal, n);
- VECCOPY(avg_normal, normal);
- VecMulf(avg_normal, 1.0f / total);
-
- VECCOPY(btail, avg_normal);
- VecMulf(btail, length);
- VecAddf(btail, btail, parent->head);
- }
-
- if (scene->toolsettings->skgen_options & SKGEN_ADAPTIVE_DISTANCE)
- {
- value = calcDistance(arc, boneStart, iter.index, parent->head, btail);
- }
- else
- {
- float n[3];
-
- VecSubf(n, btail, parent->head);
- value = calcVariance(arc, boneStart, iter.index, parent->head, n);
- }
-
- if (value > ADAPTIVE_THRESHOLD)
- {
- VECCOPY(parent->tail, btail);
-
- child = add_editbone(obedit, "Bone");
- VECCOPY(child->head, parent->tail);
- child->parent = parent;
- child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
-
- parent = child; // new child is next parent
- boneStart = iter.index; // start from end
-
- normal[0] = normal[1] = normal[2] = 0;
- total = 0;
- }
- }
-
- VECCOPY(parent->tail, tail->p);
+ initArcIterator(iter, arc, head);
- lastBone = parent; /* set last bone in the chain */
+ lastBone = subdivideArcBy(arm, arm->edbo, iter, invmat, tmat, nextAdaptativeSubdivision);
}
- return lastBone;
+ return lastBone;
}
float arcLengthRatio(ReebArc *arc)
@@ -5497,108 +5455,26 @@ float arcLengthRatio(ReebArc *arc)
return embedLength / arcLength;
}
-EditBone * subdivideByLength(Scene *scene, Object *obedit, ReebArc *arc, ReebNode *head, ReebNode *tail)
+EditBone * test_subdivideByLength(Scene *scene, Object *obedit, ReebArc *arc, ReebNode *head, ReebNode *tail)
{
EditBone *lastBone = NULL;
-
if ((scene->toolsettings->skgen_options & SKGEN_CUT_LENGTH) &&
- arcLengthRatio(arc) >= scene->toolsettings->skgen_length_ratio)
+ arcLengthRatio(arc) >= G.scene->toolsettings->skgen_length_ratio)
{
- ReebArcIterator iter;
- EmbedBucket *bucket = NULL;
- EmbedBucket *previous = NULL;
- EditBone *child = NULL;
- EditBone *parent = NULL;
- float lengthLimit = scene->toolsettings->skgen_length_limit;
- int same = 0;
-
- parent = add_editbone(obedit, "Bone");
- parent->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
- VECCOPY(parent->head, head->p);
-
- initArcIterator(&iter, arc, head);
-
- bucket = nextBucket(&iter);
+ float invmat[4][4] = { {1, 0, 0, 0},
+ {0, 1, 0, 0},
+ {0, 0, 1, 0},
+ {0, 0, 0, 1}};
+ float tmat[3][3] = { {1, 0, 0},
+ {0, 1, 0},
+ {0, 0, 1}};
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
+ bArmature *arm= obedit->data;
- while (bucket != NULL)
- {
- float *vec0 = NULL;
- float *vec1 = bucket->p;
-
- /* first bucket. Previous is head */
- if (previous == NULL)
- {
- vec0 = head->p;
- }
- /* Previous is a valid bucket */
- else
- {
- vec0 = previous->p;
- }
-
- /* If lengthLimit hits the current segment */
- if (VecLenf(vec1, parent->head) > lengthLimit)
- {
- if (same == 0)
- {
- float dv[3], off[3];
- float a, b, c, f;
-
- /* Solve quadratic distance equation */
- VecSubf(dv, vec1, vec0);
- a = Inpf(dv, dv);
-
- VecSubf(off, vec0, parent->head);
- b = 2 * Inpf(dv, off);
-
- c = Inpf(off, off) - (lengthLimit * lengthLimit);
-
- f = (-b + (float)sqrt(b * b - 4 * a * c)) / (2 * a);
-
- //printf("a %f, b %f, c %f, f %f\n", a, b, c, f);
-
- if (isnan(f) == 0 && f < 1.0f)
- {
- VECCOPY(parent->tail, dv);
- VecMulf(parent->tail, f);
- VecAddf(parent->tail, parent->tail, vec0);
- }
- else
- {
- VECCOPY(parent->tail, vec1);
- }
- }
- else
- {
- float dv[3];
-
- VecSubf(dv, vec1, vec0);
- Normalize(dv);
-
- VECCOPY(parent->tail, dv);
- VecMulf(parent->tail, lengthLimit);
- VecAddf(parent->tail, parent->tail, parent->head);
- }
-
- child = add_editbone(obedit, "Bone");
- VECCOPY(child->head, parent->tail);
- child->parent = parent;
- child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
-
- parent = child; // new child is next parent
-
- same = 1; // mark as same
- }
- else
- {
- previous = bucket;
- bucket = nextBucket(&iter);
- same = 0; // Reset same
- }
- }
- VECCOPY(parent->tail, tail->p);
+ initArcIterator(iter, arc, head);
- lastBone = parent; /* set last bone in the chain */
+ lastBone = subdivideArcBy(arm, arm->edbo, iter, invmat, tmat, nextLengthSubdivision);
}
return lastBone;
@@ -5693,13 +5569,13 @@ void generateSkeletonFromReebGraph(Scene *scene, ReebGraph *rg)
switch(scene->toolsettings->skgen_subdivisions[i])
{
case SKGEN_SUB_LENGTH:
- lastBone = subdivideByLength(scene, obedit, arc, head, tail);
+ lastBone = test_subdivideByLength(scene, obedit, arc, head, tail);
break;
case SKGEN_SUB_ANGLE:
lastBone = subdivideByAngle(scene, obedit, arc, head, tail);
break;
case SKGEN_SUB_CORRELATION:
- lastBone = subdivideByCorrelation(scene, obedit, arc, head, tail);
+ lastBone = test_subdivideByCorrelation(scene, obedit, arc, head, tail);
break;
}
}
diff --git a/source/blender/editors/armature/reeb.h b/source/blender/editors/armature/reeb.h
index c4c062196fc..6aeb0a37f78 100644
--- a/source/blender/editors/armature/reeb.h
+++ b/source/blender/editors/armature/reeb.h
@@ -25,7 +25,7 @@
#ifndef REEB_H_
#define REEB_H_
-//#define WITH_BF_REEB
+#define WITH_BF_REEB
#include "DNA_listBase.h"
@@ -60,6 +60,7 @@ typedef struct EmbedBucket {
float val;
int nv;
float p[3];
+ float no[3]; /* if non-null, normal of the bucket */
} EmbedBucket;
typedef struct ReebNode {
@@ -76,6 +77,8 @@ typedef struct ReebNode {
int symmetry_flag;
float symmetry_axis[3];
/*********************************/
+
+ float no[3];
int index;
float weight;
@@ -114,12 +117,23 @@ typedef struct ReebArc {
} ReebArc;
typedef struct ReebArcIterator {
- struct ReebArc *arc;
+ HeadFct head;
+ TailFct tail;
+ PeekFct peek;
+ NextFct next;
+ NextNFct nextN;
+ PreviousFct previous;
+ StoppedFct stopped;
+
+ float *p, *no;
+
+ int length;
int index;
+ /*********************************/
+ struct ReebArc *arc;
int start;
int end;
- int stride;
- int length;
+ int stride;
} ReebArcIterator;
struct EditMesh;
@@ -136,15 +150,9 @@ void renormalizeWeight(struct EditMesh *em, float newmax);
ReebGraph * generateReebGraph(struct EditMesh *me, int subdivisions);
ReebGraph * newReebGraph();
-void initArcIterator(struct ReebArcIterator *iter, struct ReebArc *arc, struct ReebNode *head);
-void initArcIterator2(struct ReebArcIterator *iter, struct ReebArc *arc, int start, int end);
-void initArcIteratorStart(struct ReebArcIterator *iter, struct ReebArc *arc, struct ReebNode *head, int start);
-struct EmbedBucket * nextBucket(struct ReebArcIterator *iter);
-struct EmbedBucket * nextNBucket(ReebArcIterator *iter, int n);
-struct EmbedBucket * peekBucket(ReebArcIterator *iter, int n);
-struct EmbedBucket * currentBucket(struct ReebArcIterator *iter);
-struct EmbedBucket * previousBucket(struct ReebArcIterator *iter);
-int iteratorStopped(struct ReebArcIterator *iter);
+void initArcIterator(BArcIterator *iter, struct ReebArc *arc, struct ReebNode *head);
+void initArcIterator2(BArcIterator *iter, struct ReebArc *arc, int start, int end);
+void initArcIteratorStart(BArcIterator *iter, struct ReebArc *arc, struct ReebNode *head, int start);
/* Filtering */
void filterNullReebGraph(ReebGraph *rg);
@@ -182,6 +190,7 @@ ReebNode *BIF_lowestLevelNode(ReebNode *node);
ReebGraph *BIF_graphForMultiNode(ReebGraph *rg, ReebNode *node);
void REEB_freeGraph(ReebGraph *rg);
+void REEB_freeArc(BArc *barc);
void REEB_exportGraph(ReebGraph *rg, int count);
void REEB_draw();
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 830d36dcfd8..cc1d7fb1f81 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -3490,8 +3490,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op)
Nurb *nu;
BezTriple *bezt;
BPoint *bp;
- float *fp;
- int a, b, direction= RNA_enum_get(op->ptr, "direction");
+ int a, direction= RNA_enum_get(op->ptr, "direction");
for(nu= editnurb->first; nu; nu= nu->next) {
if( nu->pntsu>1 || nu->pntsv>1) {
@@ -3500,8 +3499,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op)
bp= nu->bp;
while(a--) {
if( bp->f1 & SELECT ) {
- if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC;
- else nu->flagu |= CU_CYCLIC;
+ nu->flagu ^= CU_CYCLIC;
break;
}
bp++;
@@ -3512,8 +3510,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op)
bezt= nu->bezt;
while(a--) {
if( BEZSELECTED_HIDDENHANDLES(bezt) ) {
- if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC;
- else nu->flagu |= CU_CYCLIC;
+ nu->flagu ^= CU_CYCLIC;
break;
}
bezt++;
@@ -3526,19 +3523,8 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op)
bp= nu->bp;
while(a--) {
if( bp->f1 & SELECT ) {
- if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC;
- else {
- nu->flagu |= CU_CYCLIC;
- nu->flagu &= ~2; /* endpoint flag, fixme */
- fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN");
- b= (nu->orderu+nu->pntsu);
- memcpy(fp, nu->knotsu, sizeof(float)*b);
- MEM_freeN(nu->knotsu);
- nu->knotsu= fp;
-
- makeknots(nu, 1, 0); /* 1==u 0==uniform */
-
- }
+ nu->flagu ^= CU_CYCLIC;
+ makeknots(nu, 1, nu->flagu>>1); /* 1==u type is ignored for cyclic curves */
break;
}
bp++;
@@ -3552,38 +3538,12 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op)
if( bp->f1 & SELECT) {
if(direction==0 && nu->pntsu>1) {
- if(nu->flagu & CU_CYCLIC) nu->flagu &= ~CU_CYCLIC;
- else {
- nu->flagu |= CU_CYCLIC;
- if (check_valid_nurb_u(nu)) {
- fp= MEM_mallocN(sizeof(float)*KNOTSU(nu), "makecyclicN");
- b= (nu->orderu+nu->pntsu);
- if (nu->knotsu) { /* null if check_valid_nurb_u failed before but is valid now */
- memcpy(fp, nu->knotsu, sizeof(float)*b);
- MEM_freeN(nu->knotsu);
- }
- nu->knotsu= fp;
-
- makeknots(nu, 1, 0); /* 1==u 0==uniform */
- }
- }
+ nu->flagu ^= CU_CYCLIC;
+ makeknots(nu, 1, nu->flagu>>1); /* 1==u type is ignored for cyclic curves */
}
if(direction==1 && nu->pntsv>1) {
- if(nu->flagv & 1) nu->flagv--;
- else {
- nu->flagv++;
- if (check_valid_nurb_v(nu)) {
- fp= MEM_mallocN(sizeof(float)*KNOTSV(nu), "makecyclicN");
- b= (nu->orderv+nu->pntsv);
- if (nu->knotsv) { /* null if check_valid_nurb_v failed before but is valid now */
- memcpy(fp, nu->knotsv, sizeof(float)*b);
- MEM_freeN(nu->knotsv);
- }
- nu->knotsv= fp;
-
- makeknots(nu, 2, 0); /* 2==v 0==uniform */
- }
- }
+ nu->flagv ^= CU_CYCLIC;
+ makeknots(nu, 2, nu->flagv>>1); /* 2==v type is ignored for cyclic curves */
}
break;
}
diff --git a/source/blender/editors/gpencil/gpencil.c b/source/blender/editors/gpencil/gpencil.c
index dfe76ac6a07..7a251f2c252 100644
--- a/source/blender/editors/gpencil/gpencil.c
+++ b/source/blender/editors/gpencil/gpencil.c
@@ -944,7 +944,7 @@ static void gp_stroke_to_bonechain (bGPDlayer *gpl, bGPDstroke *gps, bArmature *
/* add new bone - note: sync with editarmature.c::add_editbone() */
{
BLI_strncpy(ebo->name, "Stroke", 32);
- unique_editbone_name(bones, ebo->name);
+ unique_editbone_name(bones, ebo->name, NULL);
BLI_addtail(bones, ebo);
diff --git a/source/blender/editors/include/BIF_transform.h b/source/blender/editors/include/BIF_transform.h
index 2cb07b35632..f8fb78d8559 100644
--- a/source/blender/editors/include/BIF_transform.h
+++ b/source/blender/editors/include/BIF_transform.h
@@ -95,6 +95,7 @@ struct TransInfo;
struct ScrArea;
struct Base;
struct Scene;
+struct Object;
void BIF_setSingleAxisConstraint(float vec[3], char *text);
void BIF_setDualAxisConstraint(float vec1[3], float vec2[3], char *text);
@@ -130,5 +131,33 @@ void ManipulatorTransform();
//int BIF_do_manipulator(struct ScrArea *sa);
//void BIF_draw_manipulator(struct ScrArea *sa);
+/* Snapping */
+
+
+typedef struct DepthPeel
+{
+ struct DepthPeel *next, *prev;
+
+ float depth;
+ float p[3];
+ float no[3];
+ struct Object *ob;
+ int flag;
+} DepthPeel;
+
+struct ListBase;
+
+typedef enum SnapMode
+{
+ SNAP_ALL = 0,
+ SNAP_NOT_SELECTED = 1,
+ SNAP_NOT_OBEDIT = 2
+} SnapMode;
+
+#define SNAP_MIN_DISTANCE 30
+
+int snapObjects(struct TransInfo *t, int *dist, float *loc, float *no, SnapMode mode);
+int peelObjects(struct TransInfo *t, struct ListBase *depth_peels, short mval[2]);
+
#endif
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 290c7bfbcad..a6eb7be8615 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -111,7 +111,7 @@ void create_vgroups_from_armature(struct Scene *scene, struct Object *ob, struct
void docenter_armature (struct Scene *scene, struct View3D *v3d, struct Object *ob, int centermode);
void auto_align_armature(struct Scene *scene, struct View3D *v3d, short mode);
-void unique_editbone_name (ListBase *edbo, char *name);
+void unique_editbone_name(struct ListBase *ebones, char *name, EditBone *bone); /* if bone is already in list, pass it as param to ignore it */
void armature_bone_rename(Object *ob, char *oldnamep, char *newnamep);
void undo_push_armature(struct bContext *C, char *name);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 128af0fd36a..fbe6362db7c 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -91,6 +91,7 @@ void viewline(struct ARegion *ar, struct View3D *v3d, short mval[2], float ray_s
void viewray(struct ARegion *ar, struct View3D *v3d, short mval[2], float ray_start[3], float ray_normal[3]);
int get_view3d_viewplane(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize);
+int get_view3d_ortho(struct View3D *v3d, struct RegionView3D *rv3d);
void view3d_get_object_project_mat(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4], float vmat[4][4]);
void view3d_project_float(struct ARegion *a, float *vec, float *adr, float mat[4][4]);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 79c0cf5eae0..194ccd285bf 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -2424,12 +2424,13 @@ void autocomplete_do_name(AutoComplete *autocpl, const char *name)
}
void autocomplete_end(AutoComplete *autocpl, char *autoname)
-{
+{
if(autocpl->truncate[0])
BLI_strncpy(autoname, autocpl->truncate, autocpl->maxlen);
- else
- BLI_strncpy(autoname, autocpl->startname, autocpl->maxlen);
-
+ else {
+ if (autoname != autocpl->startname) /* dont copy a string over its self */
+ BLI_strncpy(autoname, autocpl->startname, autocpl->maxlen);
+ }
MEM_freeN(autocpl->truncate);
MEM_freeN(autocpl);
}
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index fd6719d63bb..bff2e0dd81b 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -5101,7 +5101,11 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
if(G.f & G_TEXTUREPAINT) {
G.f &= ~G_TEXTUREPAINT;
+
+ if(U.glreslimit != 0)
+ GPU_free_images();
GPU_paint_set_mipmap(1);
+
toggle_paint_cursor(C, 0);
}
else {
@@ -5112,7 +5116,11 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
NULL, me->totface);
brush_check_exists(&scene->toolsettings->imapaint.brush);
+
+ if(U.glreslimit != 0)
+ GPU_free_images();
GPU_paint_set_mipmap(0);
+
toggle_paint_cursor(C, 1);
}
diff --git a/source/blender/editors/space_buttons/SConscript b/source/blender/editors/space_buttons/SConscript
index d36dd89b681..541da52f7f9 100644
--- a/source/blender/editors/space_buttons/SConscript
+++ b/source/blender/editors/space_buttons/SConscript
@@ -7,4 +7,12 @@ incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../makesrna ../../render/extern/include'
-env.BlenderLib ( 'bf_editors_space_buttons', sources, Split(incs), [], libtype=['core'], priority=[120] )
+defs = []
+
+if env['WITH_BF_GAMEENGINE']:
+ defs.append('GAMEBLENDER=1')
+
+ if env['WITH_BF_SOLID']:
+ defs.append('USE_SUMO_SOLID')
+
+env.BlenderLib ( 'bf_editors_space_buttons', sources, Split(incs), defs, libtype=['core'], priority=[120] )
diff --git a/source/blender/editors/space_file/Makefile b/source/blender/editors/space_file/Makefile
index 7a41f66fb1d..480a4ee3889 100644
--- a/source/blender/editors/space_file/Makefile
+++ b/source/blender/editors/space_file/Makefile
@@ -54,3 +54,8 @@ CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
# own include
CPPFLAGS += -I../include
+
+ifeq ($(WITH_OPENJPEG),true)
+ CPPFLAGS += -DWITH_OPENJPEG
+endif
+
diff --git a/source/blender/editors/space_image/image_panels.c b/source/blender/editors/space_image/image_panels.c
index c0fe8afd036..9f6a379ff2b 100644
--- a/source/blender/editors/space_image/image_panels.c
+++ b/source/blender/editors/space_image/image_panels.c
@@ -459,6 +459,7 @@ static void image_panel_view_properties(const bContext *C, ARegion *ar)
uiDefButBitI(block, TOG, ME_DRAWEDGES, B_REDR, "Edges", 70, 30,60,19, &me->drawflag, 0, 0, 0, 0, "Displays selected edges using hilights in the 3d view and UV editor");
uiDefButBitI(block, TOG, SI_DRAWSHADOW, B_REDR, "Final Shadow", 130, 30,110,19, &sima->flag, 0, 0, 0, 0, "Draw the final result from the objects modifiers");
+ uiDefButBitI(block, TOG, SI_DRAW_OTHER, B_REDR, "Other Objs", 230, 30, 80, 19, &sima->flag, 0, 0, 0, 0, "Also draw all 3d view selected mesh objects that use this image");
uiDefButBitI(block, TOG, SI_DRAW_STRETCH, B_REDR, "UV Stretch", 10,0,100,19, &sima->flag, 0, 0, 0, 0, "Difference between UV's and the 3D coords (blue for low distortion, red is high)");
if (sima->flag & SI_DRAW_STRETCH) {
diff --git a/source/blender/editors/space_info/SConscript b/source/blender/editors/space_info/SConscript
index faedcbfa587..9723a7fcfe2 100644
--- a/source/blender/editors/space_info/SConscript
+++ b/source/blender/editors/space_info/SConscript
@@ -6,4 +6,12 @@ sources = env.Glob('*.c')
incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf ../../blenfont'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
-env.BlenderLib ( 'bf_editors_space_info', sources, Split(incs), [], libtype=['core'], priority=[70] )
+defs = []
+
+if env['WITH_BF_GAMEENGINE']:
+ defs.append('GAMEBLENDER=1')
+
+ if env['WITH_BF_SOLID']:
+ defs.append('USE_SUMO_SOLID')
+
+env.BlenderLib ( 'bf_editors_space_info', sources, Split(incs), defs, libtype=['core'], priority=[70] )
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index a9a3591c54f..0aad0cdd775 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -169,7 +169,7 @@ Sequence *get_forground_frame_seq(Scene *scene, int frame)
if(!ed) return NULL;
for (seq=ed->seqbasep->first; seq; seq= seq->next) {
- if(seq->startdisp > frame || seq->enddisp <= frame)
+ if(seq->flag & SEQ_MUTE || seq->startdisp > frame || seq->enddisp <= frame)
continue;
/* only use elements you can see - not */
if (ELEM6(seq->type, SEQ_IMAGE, SEQ_META, SEQ_SCENE, SEQ_MOVIE, SEQ_MOVIE_AND_HD_SOUND, SEQ_COLOR)) {
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index 5eb7caf50f1..1807de9efbb 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -353,9 +353,10 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
solidtex= 1;
Gtexdraw.islit= -1;
}
- else
+ else {
/* draw with lights in the scene otherwise */
- Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat);
+ Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, get_view3d_ortho(v3d, rv3d));
+ }
obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index f9a5195860d..2bb532288ef 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -1097,14 +1097,15 @@ void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPo
float *co = dl?dl->verts:NULL;
float pmat[4][4], vmat[4][4];
int i, N = lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
- short s[2];
+ short s[2] = {IS_CLIPPED, 0};
view3d_get_object_project_mat(vc->rv3d, vc->obedit, pmat, vmat);
for (i=0; i<N; i++, bp++, co+=3) {
if (bp->hide==0) {
view3d_project_short_clip(vc->ar, dl?co:bp->vec, s, pmat, vmat);
- func(userData, bp, s[0], s[1]);
+ if (s[0] != IS_CLIPPED)
+ func(userData, bp, s[0], s[1]);
}
}
}
@@ -1198,16 +1199,18 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, float *co
{
struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData;
EditVert *eve = EM_get_vert_for_index(index);
- short s[2];
if (eve->h==0) {
+ short s[2]= {IS_CLIPPED, 0};
+
if (data->clipVerts) {
view3d_project_short_clip(data->vc.ar, co, s, data->pmat, data->vmat);
} else {
view3d_project_short_noclip(data->vc.ar, co, s, data->pmat);
}
- data->func(data->userData, eve, s[0], s[1], index);
+ if (s[0]!=IS_CLIPPED)
+ data->func(data->userData, eve, s[0], s[1], index);
}
}
@@ -1309,7 +1312,7 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb
{
Curve *cu= vc->obedit->data;
float pmat[4][4], vmat[4][4];
- short s[2];
+ short s[2] = {IS_CLIPPED, 0};
Nurb *nu;
int i;
@@ -1345,7 +1348,8 @@ void nurbs_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, Nurb
if(bp->hide==0) {
view3d_project_short_clip(vc->ar, bp->vec, s, pmat, vmat);
- func(userData, nu, bp, NULL, -1, s[0], s[1]);
+ if (s[0] != IS_CLIPPED)
+ func(userData, nu, bp, NULL, -1, s[0], s[1]);
}
}
}
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index d3af8a05faf..26b6dcc22ff 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -1557,6 +1557,144 @@ static void view3d_panel_gpencil(const bContext *C, ARegion *ar, short cntrl) //
uiEndBlock(C, block);
}
+/* XXX etch-a-ton */
+#if 0
+static void delete_sketch_armature(void *arg1, void *arg2)
+{
+ BIF_deleteSketch();
+}
+
+static void convert_sketch_armature(void *arg1, void *arg2)
+{
+ BIF_convertSketch();
+}
+
+static void assign_template_sketch_armature(void *arg1, void *arg2)
+{
+ int index = *(int*)arg1;
+ BIF_setTemplate(index);
+}
+static void view3d_panel_bonesketch_spaces(short cntrl)
+{
+ static int template_index;
+ static char joint_label[128];
+ uiBlock *block;
+ uiBut *but;
+ char *bone_name;
+ int yco = 130, height = 140;
+ int nb_joints;
+
+ /* replace with check call to sketching lib */
+ if (G.obedit && G.obedit->type == OB_ARMATURE)
+ {
+ static char subdiv_tooltip[4][64] = {
+ "Subdivide arcs based on a fixed number of bones",
+ "Subdivide arcs in bones of equal length",
+ "Subdivide arcs based on correlation",
+ "Retarget template to stroke"
+ };
+
+
+ block= uiNewBlock(&curarea->uiblocks, "view3d_panel_bonesketch_spaces", UI_EMBOSS, UI_HELV, curarea->win);
+ uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
+ uiSetPanelHandler(VIEW3D_HANDLER_BONESKETCH); // for close and esc
+
+ if(uiNewPanel(curarea, block, "Bone Sketching", "View3d", 10, 230, 250, height)==0) return;
+
+ uiNewPanelHeight(block, height);
+
+ uiBlockBeginAlign(block);
+
+ /* use real flag instead of 1 */
+ uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 160, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones");
+ uiDefButBitC(block, TOG, BONE_SKETCHING_ADJUST, B_REDR, "A", 170, yco, 20, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Adjust strokes by drawing near them");
+ uiDefButBitC(block, TOG, BONE_SKETCHING_QUICK, B_REDR, "Q", 190, yco, 20, 20, &G.scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Automatically convert and delete on stroke end");
+ yco -= 20;
+
+ but = uiDefBut(block, BUT, B_REDR, "Convert", 10,yco,100,20, 0, 0, 0, 0, 0, "Convert sketch to armature");
+ uiButSetFunc(but, convert_sketch_armature, NULL, NULL);
+
+ but = uiDefBut(block, BUT, B_REDR, "Delete", 110,yco,100,20, 0, 0, 0, 0, 0, "Delete sketch");
+ uiButSetFunc(but, delete_sketch_armature, NULL, NULL);
+ yco -= 20;
+
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+
+ uiDefButC(block, MENU, B_REDR, "Subdivision Method%t|Length%x1|Adaptative%x2|Fixed%x0|Template%x3", 10,yco,60,19, &G.scene->toolsettings->bone_sketching_convert, 0, 0, 0, 0, subdiv_tooltip[(unsigned char)G.scene->toolsettings->bone_sketching_convert]);
+
+ switch(G.scene->toolsettings->bone_sketching_convert)
+ {
+ case SK_CONVERT_CUT_LENGTH:
+ uiDefButF(block, NUM, B_REDR, "Lim:", 70, yco, 140, 19, &G.scene->toolsettings->skgen_length_limit,0.1,50.0, 10, 0, "Maximum length of the subdivided bones");
+ yco -= 20;
+ break;
+ case SK_CONVERT_CUT_ADAPTATIVE:
+ uiDefButF(block, NUM, B_REDR, "Thres:", 70, yco, 140, 19, &G.scene->toolsettings->skgen_correlation_limit,0.0, 1.0, 0.01, 0, "Correlation threshold for subdivision");
+ yco -= 20;
+ break;
+ default:
+ case SK_CONVERT_CUT_FIXED:
+ uiDefButC(block, NUM, B_REDR, "Num:", 70, yco, 140, 19, &G.scene->toolsettings->skgen_subdivision_number,1, 100, 1, 5, "Number of subdivided bones");
+ yco -= 20;
+ break;
+ case SK_CONVERT_RETARGET:
+ uiDefButC(block, ROW, B_DIFF, "No", 70, yco, 40,19, &G.scene->toolsettings->skgen_retarget_roll, 0, 0, 0, 0, "No special roll treatment");
+ uiDefButC(block, ROW, B_DIFF, "View", 110, yco, 50,19, &G.scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_VIEW, 0, 0, "Roll bones perpendicular to view");
+ uiDefButC(block, ROW, B_DIFF, "Joint", 160, yco, 50,19, &G.scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_JOINT, 0, 0, "Roll bones relative to joint bend");
+ yco -= 30;
+
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ /* button here to select what to do (copy or not), template, ...*/
+
+ BIF_makeListTemplates();
+ template_index = BIF_currentTemplate();
+
+ but = uiDefButI(block, MENU, B_REDR, BIF_listTemplates(), 10,yco,200,19, &template_index, 0, 0, 0, 0, "Template");
+ uiButSetFunc(but, assign_template_sketch_armature, &template_index, NULL);
+
+ yco -= 20;
+
+ uiDefButF(block, NUM, B_DIFF, "A:", 10, yco, 66,19, &G.scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0, "Angle Weight");
+ uiDefButF(block, NUM, B_DIFF, "L:", 76, yco, 67,19, &G.scene->toolsettings->skgen_retarget_length_weight, 0, 10, 1, 0, "Length Weight");
+ uiDefButF(block, NUM, B_DIFF, "D:", 143,yco, 67,19, &G.scene->toolsettings->skgen_retarget_distance_weight, 0, 10, 1, 0, "Distance Weight");
+ yco -= 20;
+
+ uiDefBut(block, TEX,B_DIFF,"S:", 10, yco, 90, 20, G.scene->toolsettings->skgen_side_string, 0.0, 8.0, 0, 0, "Text to replace &S with");
+ uiDefBut(block, TEX,B_DIFF,"N:", 100, yco, 90, 20, G.scene->toolsettings->skgen_num_string, 0.0, 8.0, 0, 0, "Text to replace &N with");
+ uiDefIconButBitC(block, TOG, SK_RETARGET_AUTONAME, B_DIFF, ICON_AUTO,190,yco,20,20, &G.scene->toolsettings->skgen_retarget_options, 0, 0, 0, 0, "Use Auto Naming");
+ yco -= 20;
+
+ /* auto renaming magic */
+ uiBlockEndAlign(block);
+
+ nb_joints = BIF_nbJointsTemplate();
+
+ if (nb_joints == -1)
+ {
+ nb_joints = G.totvertsel;
+ }
+
+ bone_name = BIF_nameBoneTemplate();
+
+ BLI_snprintf(joint_label, 32, "%i joints: %s", nb_joints, bone_name);
+
+ uiDefBut(block, LABEL, 1, joint_label, 10, yco, 200, 20, NULL, 0.0, 0.0, 0, 0, "");
+ yco -= 20;
+ break;
+ }
+
+ uiBlockEndAlign(block);
+
+ uiDefButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_DIFF, "Peel Objects", 10, yco, 200, 20, &G.scene->snap_flag, 0, 0, 0, 0, "Peel whole objects as one");
+
+ if(yco < 0) uiNewPanelHeight(block, height-yco);
+ }
+}
+#endif
void view3d_buttons_area_defbuts(const bContext *C, ARegion *ar)
{
@@ -1570,6 +1708,7 @@ void view3d_buttons_area_defbuts(const bContext *C, ARegion *ar)
view3d_panel_transform_spaces(C, ar, 0);
if(0)
view3d_panel_gpencil(C, ar, 0);
+ // XXX etch-a-ton view3d_panel_bonesketch_spaces(C, ar, 0);
uiDrawPanels(C, 1); /* 1 = align */
uiMatchPanelsView2d(ar); /* sets v2d->totrct */
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 80728a77244..7531193dc92 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -2053,6 +2053,8 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
// if (v3d->flag2 & V3D_DISPGP)
// draw_gpencil_3dview(ar, 1);
+ // XXX etch-a-ton BDR_drawSketch();
+
ED_region_pixelspace(ar);
/* Draw Sculpt Mode brush XXX (removed) */
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index a7dd419f672..d1ac6976515 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -133,6 +133,7 @@ static int retopo_mesh_paint_check() {return 0;}
#define VIEW3D_HANDLER_MULTIRES 5
#define VIEW3D_HANDLER_TRANSFORM 6
#define VIEW3D_HANDLER_GREASEPENCIL 7
+#define VIEW3D_HANDLER_BONESKETCH 8
/* end XXX ************* */
@@ -3718,6 +3719,9 @@ static void do_view3d_edit_armaturemenu(bContext *C, void *arg, int event)
case 22: /* separate */
separate_armature();
break;
+ case 23: /* bone sketching panel */
+ add_blockhandler(curarea, VIEW3D_HANDLER_BONESKETCH, UI_PNL_UNSTOW);
+ break;
}
#endif
@@ -3796,6 +3800,7 @@ static uiBlock *view3d_edit_armaturemenu(bContext *C, ARegion *ar, void *arg_unu
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Transform Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Bone Sketching|P", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 23, "");
uiDefIconTextBlockBut(block, view3d_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, view3d_edit_mirrormenu, NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, menuwidth, 19, "");
uiDefIconTextBlockBut(block, view3d_edit_snapmenu, NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 19, "");
@@ -4847,6 +4852,7 @@ static char *snapmode_pup(void)
str += sprintf(str, "%s", "|Vertex%x0");
str += sprintf(str, "%s", "|Edge%x1");
str += sprintf(str, "%s", "|Face%x2");
+ str += sprintf(str, "%s", "|Volume%x3");
return string;
}
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index b1bd39a66da..072aab55ed4 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -71,6 +71,9 @@
#include "ED_screen.h"
#include "ED_view3d.h"
+// XXX etch-a-ton #include "BIF_sketch.h"
+// XXX etch-a-ton #include "BDR_sketch.h"
+
#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -802,7 +805,28 @@ void project_float_noclip(ARegion *ar, float *vec, float *adr)
}
}
-
+int get_view3d_ortho(View3D *v3d, RegionView3D *rv3d)
+{
+ Camera *cam;
+
+ if(rv3d->persp==V3D_CAMOB) {
+ if(v3d->camera && v3d->camera->type==OB_CAMERA) {
+ cam= v3d->camera->data;
+
+ if(cam && cam->type==CAM_ORTHO)
+ return 1;
+ else
+ return 0;
+ }
+ else
+ return 0;
+ }
+
+ if(rv3d->persp==V3D_ORTHO)
+ return 1;
+
+ return 0;
+}
/* also exposed in previewrender.c */
int get_view3d_viewplane(View3D *v3d, RegionView3D *rv3d, int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize)
@@ -1120,8 +1144,13 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b
if(vc->obedit && vc->obedit->type==OB_MBALL) {
draw_object(scene, ar, v3d, BASACT, DRAW_PICKING|DRAW_CONSTCOLOR);
}
- else if ((vc->obedit && vc->obedit->type==OB_ARMATURE)) {
- draw_object(scene, ar, v3d, BASACT, DRAW_PICKING|DRAW_CONSTCOLOR);
+ else if((vc->obedit && vc->obedit->type==OB_ARMATURE)) {
+ /* XXX etch-a-ton if(BIF_fullSketchMode()) {
+ BDR_drawSketchNames();
+ }
+ else*/ {
+ draw_object(scene, ar, v3d, BASACT, DRAW_PICKING|DRAW_CONSTCOLOR);
+ }
}
else {
Base *base;
@@ -1236,7 +1265,7 @@ static void initlocalview(Scene *scene, ScrArea *sa)
locallay= free_localbit();
if(locallay==0) {
- printf("Sorry, no more than 8 localviews\n"); // XXX error
+ printf("Sorry, no more than 8 localviews\n"); // XXX error
ok= 0;
}
else {
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 6676459e59f..6a94dc68d3e 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -671,7 +671,7 @@ static void bone_children_clear_transflag(TransInfo *t, ListBase *lb)
{
bone->flag |= BONE_HINGE_CHILD_TRANSFORM;
}
- else if (bone->flag & BONE_TRANSFORM && (t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL))
+ else if (bone->flag & BONE_TRANSFORM && (t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL) && t->around == V3D_LOCAL)
{
bone->flag |= BONE_TRANSFORM_CHILD;
}
@@ -4049,7 +4049,7 @@ static void set_trans_object_base_flags(bContext *C, TransInfo *t)
if(parsel)
{
- if (t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL)
+ if ((t->mode == TFM_ROTATION || t->mode == TFM_TRACKBALL) && t->around == V3D_LOCAL)
{
base->flag |= BA_TRANSFORM_CHILD;
}
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 447c4b810ab..73b858aa8ca 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -34,6 +34,8 @@
#include "PIL_time.h"
+#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_meshdata_types.h" // Temporary, for snapping to other unselected meshes
@@ -44,6 +46,7 @@
#include "BLI_arithb.h"
#include "BLI_editVert.h"
+#include "BLI_blenlib.h"
//#include "BDR_drawobject.h"
//
@@ -57,6 +60,8 @@
//#include "BIF_drawimage.h"
//#include "BIF_editmesh.h"
+#include "BIF_transform.h"
+
#include "BKE_global.h"
#include "BKE_utildefines.h"
#include "BKE_DerivedMesh.h"
@@ -64,6 +69,7 @@
#include "BKE_anim.h" /* for duplis */
#include "BKE_context.h"
+#include "ED_armature.h"
#include "ED_image.h"
#include "ED_mesh.h"
#include "ED_uvedit.h"
@@ -100,12 +106,6 @@ float RotationBetween(TransInfo *t, float p1[3], float p2[3]);
float TranslationBetween(TransInfo *t, float p1[3], float p2[3]);
float ResizeBetween(TransInfo *t, float p1[3], float p2[3]);
-/* Modes */
-#define SNAP_ALL 0
-#define SNAP_NOT_SELECTED 1
-#define SNAP_NOT_OBEDIT 2
-int snapObjects(TransInfo *t, int *dist, float *loc, float *no, int mode);
-
/****************** IMPLEMENTATIONS *********************/
@@ -113,7 +113,7 @@ int BIF_snappingSupported(Object *obedit)
{
int status = 0;
- if (obedit == NULL || obedit->type==OB_MESH) /* only support object or mesh */
+ if (obedit == NULL || ELEM(obedit->type, OB_MESH, OB_ARMATURE)) /* only support object mesh or armature */
{
status = 1;
}
@@ -289,7 +289,7 @@ void initSnapping(TransInfo *t)
/* Edit mode */
if (t->tsnap.applySnap != NULL && // A snapping function actually exist
(scene->snap_flag & SCE_SNAP) && // Only if the snap flag is on
- (obedit != NULL && obedit->type==OB_MESH) ) // Temporary limited to edit mode meshes
+ (obedit != NULL && ELEM(obedit->type, OB_MESH, OB_ARMATURE)) ) // Temporary limited to edit mode meshes or armature
{
t->tsnap.status |= SNAP_ON;
t->tsnap.modePoint = SNAP_GEO;
@@ -503,85 +503,162 @@ void CalcSnapGrid(TransInfo *t, float *vec)
void CalcSnapGeometry(TransInfo *t, float *vec)
{
- /* Object mode */
- if (t->obedit == NULL)
+ if (t->spacetype == SPACE_VIEW3D)
{
- if (t->spacetype == SPACE_VIEW3D)
+ float loc[3];
+ float no[3];
+ int found = 0;
+ int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
+ SnapMode mode;
+
+ if (t->scene->snap_mode == SCE_SNAP_MODE_VOLUME)
{
- float vec[3];
- float no[3];
- int found = 0;
- int dist = 40; // Use a user defined value here
+ ListBase depth_peels;
+ DepthPeel *p1, *p2;
+ float *last_p = NULL;
+ float dist = FLT_MAX;
+ float p[3];
+
+ depth_peels.first = depth_peels.last = NULL;
+
+ peelObjects(t, &depth_peels, t->mval);
+
+// if (stk->nb_points > 0 && stk->points[stk->nb_points - 1].type == PT_CONTINUOUS)
+// {
+// last_p = stk->points[stk->nb_points - 1].p;
+// }
+// else if (LAST_SNAP_POINT_VALID)
+// {
+// last_p = LAST_SNAP_POINT;
+// }
- found = snapObjects(t, &dist, vec, no, t->tsnap.mode);
- if (found == 1)
+
+ for (p1 = depth_peels.first; p1; p1 = p1->next)
{
- float tangent[3];
-
- VecSubf(tangent, vec, t->tsnap.snapPoint);
- tangent[2] = 0;
-
- if (Inpf(tangent, tangent) > 0)
+ if (p1->flag == 0)
{
- VECCOPY(t->tsnap.snapTangent, tangent);
+ float vec[3];
+ float new_dist;
+
+ p2 = NULL;
+ p1->flag = 1;
+
+ /* if peeling objects, take the first and last from each object */
+ if (t->scene->snap_flag & SCE_SNAP_PEEL_OBJECT)
+ {
+ DepthPeel *peel;
+ for (peel = p1->next; peel; peel = peel->next)
+ {
+ if (peel->ob == p1->ob)
+ {
+ peel->flag = 1;
+ p2 = peel;
+ }
+ }
+ }
+ /* otherwise, pair first with second and so on */
+ else
+ {
+ for (p2 = p1->next; p2 && p2->ob != p1->ob; p2 = p2->next)
+ {
+ /* nothing to do here */
+ }
+ }
+
+ if (p2)
+ {
+ p2->flag = 1;
+
+ VecAddf(vec, p1->p, p2->p);
+ VecMulf(vec, 0.5f);
+ }
+ else
+ {
+ VECCOPY(vec, p1->p);
+ }
+
+ if (last_p == NULL)
+ {
+ VECCOPY(p, vec);
+ dist = 0;
+ break;
+ }
+
+ new_dist = VecLenf(last_p, vec);
+
+ if (new_dist < dist)
+ {
+ VECCOPY(p, vec);
+ dist = new_dist;
+ }
}
-
- VECCOPY(t->tsnap.snapPoint, vec);
- VECCOPY(t->tsnap.snapNormal, no);
-
- t->tsnap.status |= POINT_INIT;
}
- else
+
+ if (dist != FLT_MAX)
{
- t->tsnap.status &= ~POINT_INIT;
+ VECCOPY(loc, p);
+ found = 1;
}
+
+ BLI_freelistN(&depth_peels);
}
- }
- /* Mesh edit mode */
- else if (t->obedit->type==OB_MESH)
- {
- if (t->spacetype == SPACE_VIEW3D)
+ else
{
- float vec[3];
- float no[3];
- int found = 0;
- int dist = 40; // Use a user defined value here
-
- found = snapObjects(t, &dist, vec, no, t->tsnap.mode);
- if (found == 1)
+ if (t->obedit == NULL)
{
- VECCOPY(t->tsnap.snapPoint, vec);
- VECCOPY(t->tsnap.snapNormal, no);
-
- t->tsnap.status |= POINT_INIT;
+ mode = SNAP_NOT_SELECTED;
}
else
{
- t->tsnap.status &= ~POINT_INIT;
+ mode = SNAP_NOT_OBEDIT;
}
+
+ found = snapObjects(t, &dist, loc, no, mode);
}
- else if (t->spacetype == SPACE_IMAGE)
+
+ if (found == 1)
{
- /* same as above but for UV's */
- Image *ima= ED_space_image(t->sa->spacedata.first);
- float aspx, aspy, co[2];
+ float tangent[3];
- UI_view2d_region_to_view(&t->ar->v2d, t->mval[0], t->mval[1], co, co+1);
-
- if(ED_uvedit_nearest_uv(t->scene, t->obedit, ima, co, t->tsnap.snapPoint))
- {
- ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
- t->tsnap.snapPoint[0] *= aspx;
- t->tsnap.snapPoint[1] *= aspy;
-
- Mat4MulVecfl(t->obedit->obmat, t->tsnap.snapPoint);
-
- t->tsnap.status |= POINT_INIT;
- }
- else
+ VecSubf(tangent, loc, t->tsnap.snapPoint);
+ tangent[2] = 0;
+
+ if (Inpf(tangent, tangent) > 0)
{
- t->tsnap.status &= ~POINT_INIT;
+ VECCOPY(t->tsnap.snapTangent, tangent);
}
+
+ VECCOPY(t->tsnap.snapPoint, loc);
+ VECCOPY(t->tsnap.snapNormal, no);
+
+ t->tsnap.status |= POINT_INIT;
+ }
+ else
+ {
+ t->tsnap.status &= ~POINT_INIT;
+ }
+ }
+ else if (t->spacetype == SPACE_IMAGE && t->obedit != NULL && t->obedit->type==OB_MESH)
+ { /* same as above but for UV's */
+ /* same as above but for UV's */
+ Image *ima= ED_space_image(t->sa->spacedata.first);
+ float aspx, aspy, co[2];
+
+ UI_view2d_region_to_view(&t->ar->v2d, t->mval[0], t->mval[1], co, co+1);
+
+ if(ED_uvedit_nearest_uv(t->scene, t->obedit, ima, co, t->tsnap.snapPoint))
+ {
+ ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
+ t->tsnap.snapPoint[0] *= aspx;
+ t->tsnap.snapPoint[1] *= aspy;
+
+ Mat4MulVecfl(t->obedit->obmat, t->tsnap.snapPoint);
+
+ t->tsnap.status |= POINT_INIT;
+ }
+ else
+ {
+ t->tsnap.status &= ~POINT_INIT;
}
}
}
@@ -757,6 +834,251 @@ void TargetSnapClosest(TransInfo *t)
}
/*================================================================*/
+int snapFace(TransInfo *t, float v1co[3], float v2co[3], float v3co[3], float *v4co, short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth)
+{
+ float lambda;
+ int result;
+ int retval = 0;
+
+ result = RayIntersectsTriangleThreshold(ray_start_local, ray_normal_local, v1co, v2co, v3co, &lambda, NULL, 0.001);
+
+ if (result) {
+ float location[3], normal[3];
+ float intersect[3];
+ float new_depth;
+ int screen_loc[2];
+ int new_dist;
+
+ VECCOPY(intersect, ray_normal_local);
+ VecMulf(intersect, lambda);
+ VecAddf(intersect, intersect, ray_start_local);
+
+ VECCOPY(location, intersect);
+
+ if (v4co)
+ CalcNormFloat4(v1co, v2co, v3co, v4co, normal);
+ else
+ CalcNormFloat(v1co, v2co, v3co, normal);
+
+ Mat4MulVecfl(obmat, location);
+
+ new_depth = VecLenf(location, ray_start);
+
+ project_int(t->ar, location, screen_loc);
+ new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
+
+ if (new_dist <= *dist && new_depth < *depth)
+ {
+ *depth = new_depth;
+ retval = 1;
+
+ VECCOPY(loc, location);
+ VECCOPY(no, normal);
+
+ Mat3MulVecfl(timat, no);
+ Normalize(no);
+
+ *dist = new_dist;
+ }
+ }
+
+ return retval;
+}
+
+int snapEdge(TransInfo *t, float v1co[3], short v1no[3], float v2co[3], short v2no[3], short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth)
+{
+ float intersect[3] = {0, 0, 0}, ray_end[3], dvec[3];
+ int result;
+ int retval = 0;
+
+ VECCOPY(ray_end, ray_normal_local);
+ VecMulf(ray_end, 2000);
+ VecAddf(ray_end, ray_start_local, ray_end);
+
+ result = LineIntersectLine(v1co, v2co, ray_start_local, ray_end, intersect, dvec); /* dvec used but we don't care about result */
+
+ if (result)
+ {
+ float edge_loc[3], vec[3];
+ float mul;
+
+ /* check for behind ray_start */
+ VecSubf(dvec, intersect, ray_start_local);
+
+ VecSubf(edge_loc, v1co, v2co);
+ VecSubf(vec, intersect, v2co);
+
+ mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc);
+
+ if (mul > 1) {
+ mul = 1;
+ VECCOPY(intersect, v1co);
+ }
+ else if (mul < 0) {
+ mul = 0;
+ VECCOPY(intersect, v2co);
+ }
+
+ if (Inpf(ray_normal_local, dvec) > 0)
+ {
+ float location[3];
+ float new_depth;
+ int screen_loc[2];
+ int new_dist;
+
+ VECCOPY(location, intersect);
+
+ Mat4MulVecfl(obmat, location);
+
+ new_depth = VecLenf(location, ray_start);
+
+ project_int(t->ar, location, screen_loc);
+ new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
+
+ /* 10% threshold if edge is closer but a bit further
+ * this takes care of series of connected edges a bit slanted w.r.t the viewport
+ * otherwise, it would stick to the verts of the closest edge and not slide along merrily
+ * */
+ if (new_dist <= *dist && new_depth < *depth * 1.001)
+ {
+ float n1[3], n2[3];
+
+ *depth = new_depth;
+ retval = 1;
+
+ VecSubf(edge_loc, v1co, v2co);
+ VecSubf(vec, intersect, v2co);
+
+ mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc);
+
+ if (no)
+ {
+ NormalShortToFloat(n1, v1no);
+ NormalShortToFloat(n2, v2no);
+ VecLerpf(no, n2, n1, mul);
+ Mat3MulVecfl(timat, no);
+ Normalize(no);
+ }
+
+ VECCOPY(loc, location);
+
+ *dist = new_dist;
+ }
+ }
+ }
+
+ return retval;
+}
+
+int snapVertex(TransInfo *t, float vco[3], short vno[3], short mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float *loc, float *no, int *dist, float *depth)
+{
+ int retval = 0;
+ float dvec[3];
+
+ VecSubf(dvec, vco, ray_start_local);
+
+ if (Inpf(ray_normal_local, dvec) > 0)
+ {
+ float location[3];
+ float new_depth;
+ int screen_loc[2];
+ int new_dist;
+
+ VECCOPY(location, vco);
+
+ Mat4MulVecfl(obmat, location);
+
+ new_depth = VecLenf(location, ray_start);
+
+ project_int(t->ar, location, screen_loc);
+ new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
+
+ if (new_dist <= *dist && new_depth < *depth)
+ {
+ *depth = new_depth;
+ retval = 1;
+
+ VECCOPY(loc, location);
+
+ if (no)
+ {
+ NormalShortToFloat(no, vno);
+ Mat3MulVecfl(timat, no);
+ Normalize(no);
+ }
+
+ *dist = new_dist;
+ }
+ }
+
+ return retval;
+}
+
+int snapArmature(TransInfo *t, Object *ob, bArmature *arm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth)
+{
+ float imat[4][4];
+ float ray_start_local[3], ray_normal_local[3];
+ int retval = 0;
+
+ Mat4Invert(imat, obmat);
+
+ VECCOPY(ray_start_local, ray_start);
+ VECCOPY(ray_normal_local, ray_normal);
+
+ Mat4MulVecfl(imat, ray_start_local);
+ Mat4Mul3Vecfl(imat, ray_normal_local);
+
+ if(arm->edbo)
+ {
+ EditBone *eBone;
+
+ for (eBone=arm->edbo->first; eBone; eBone=eBone->next) {
+ if (eBone->layer & arm->layer) {
+ /* skip hidden or moving (selected) bones */
+ if ((eBone->flag & (BONE_HIDDEN_A|BONE_ROOTSEL|BONE_TIPSEL))==0) {
+ switch (t->scene->snap_mode)
+ {
+ case SCE_SNAP_MODE_VERTEX:
+ retval |= snapVertex(t, eBone->head, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
+ retval |= snapVertex(t, eBone->tail, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
+ break;
+ case SCE_SNAP_MODE_EDGE:
+ retval |= snapEdge(t, eBone->head, NULL, eBone->tail, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
+ break;
+ }
+ }
+ }
+ }
+ }
+ else if (ob->pose && ob->pose->chanbase.first)
+ {
+ bPoseChannel *pchan;
+ Bone *bone;
+
+ for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+ bone= pchan->bone;
+ /* skip hidden bones */
+ if (bone && !(bone->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG))) {
+ float *head_vec = pchan->pose_head;
+ float *tail_vec = pchan->pose_tail;
+
+ switch (t->scene->snap_mode)
+ {
+ case SCE_SNAP_MODE_VERTEX:
+ retval |= snapVertex(t, head_vec, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
+ retval |= snapVertex(t, tail_vec, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
+ break;
+ case SCE_SNAP_MODE_EDGE:
+ retval |= snapEdge(t, head_vec, NULL, tail_vec, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
+ break;
+ }
+ }
+ }
+ }
+
+ return retval;
+}
+
int snapDerivedMesh(TransInfo *t, Object *ob, DerivedMesh *dm, EditMesh *em, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth)
{
int retval = 0;
@@ -810,8 +1132,6 @@ int snapDerivedMesh(TransInfo *t, Object *ob, DerivedMesh *dm, EditMesh *em, flo
for( i = 0; i < totface; i++) {
EditFace *efa = NULL;
MFace *f = faces + i;
- float lambda;
- int result;
test = 1; /* reset for every face */
@@ -844,91 +1164,20 @@ int snapDerivedMesh(TransInfo *t, Object *ob, DerivedMesh *dm, EditMesh *em, flo
if (test)
{
- result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, &lambda, NULL);
+ int result;
+ float *v4co = NULL;
- if (result) {
- float location[3], normal[3];
- float intersect[3];
- float new_depth;
- int screen_loc[2];
- int new_dist;
-
- VECCOPY(intersect, ray_normal_local);
- VecMulf(intersect, lambda);
- VecAddf(intersect, intersect, ray_start_local);
-
- VECCOPY(location, intersect);
-
- if (f->v4)
- CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal);
- else
- CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal);
-
- Mat4MulVecfl(obmat, location);
-
- new_depth = VecLenf(location, ray_start);
-
- project_int(t->ar, location, screen_loc);
- new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
-
- if (new_dist <= *dist && new_depth < *depth)
- {
- *depth = new_depth;
- retval = 1;
-
- VECCOPY(loc, location);
- VECCOPY(no, normal);
-
- Mat3MulVecfl(timat, no);
- Normalize(no);
-
- *dist = new_dist;
- }
+ if (f->v4)
+ {
+ v4co = verts[f->v4].co;
}
-
+
+ result = snapFace(t, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, v4co, mval, ray_start, ray_start_local, ray_normal_local, obmat, timat, loc, no, dist, depth);
+ retval |= result;
+
if (f->v4 && result == 0)
{
- result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, &lambda, NULL);
-
- if (result) {
- float location[3], normal[3];
- float intersect[3];
- float new_depth;
- int screen_loc[2];
- int new_dist;
-
- VECCOPY(intersect, ray_normal_local);
- VecMulf(intersect, lambda);
- VecAddf(intersect, intersect, ray_start_local);
-
- VECCOPY(location, intersect);
-
- if (f->v4)
- CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal);
- else
- CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal);
-
- Mat4MulVecfl(obmat, location);
-
- new_depth = VecLenf(location, ray_start);
-
- project_int(t->ar, location, screen_loc);
- new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
-
- if (new_dist <= *dist && new_depth < *depth)
- {
- *depth = new_depth;
- retval = 1;
-
- VECCOPY(loc, location);
- VECCOPY(no, normal);
-
- Mat3MulVecfl(timat, no);
- Normalize(no);
-
- *dist = new_dist;
- }
- }
+ retval |= snapFace(t, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, verts[f->v2].co, mval, ray_start, ray_start_local, ray_normal_local, obmat, timat, loc, no, dist, depth);
}
}
}
@@ -987,40 +1236,7 @@ int snapDerivedMesh(TransInfo *t, Object *ob, DerivedMesh *dm, EditMesh *em, flo
if (test)
{
- float dvec[3];
-
- VecSubf(dvec, v->co, ray_start_local);
-
- if (Inpf(ray_normal_local, dvec) > 0)
- {
- float location[3];
- float new_depth;
- int screen_loc[2];
- int new_dist;
-
- VECCOPY(location, v->co);
-
- Mat4MulVecfl(obmat, location);
-
- new_depth = VecLenf(location, ray_start);
-
- project_int(t->ar, location, screen_loc);
- new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
-
- if (new_dist <= *dist && new_depth < *depth)
- {
- *depth = new_depth;
- retval = 1;
-
- VECCOPY(loc, location);
-
- NormalShortToFloat(no, v->no);
- Mat3MulVecfl(timat, no);
- Normalize(no);
-
- *dist = new_dist;
- }
- }
+ retval |= snapVertex(t, v->co, v->no, mval, ray_start, ray_start_local, ray_normal_local, obmat, timat, loc, no, dist, depth);
}
}
@@ -1080,79 +1296,7 @@ int snapDerivedMesh(TransInfo *t, Object *ob, DerivedMesh *dm, EditMesh *em, flo
if (test)
{
- float intersect[3] = {0, 0, 0}, ray_end[3], dvec[3];
- int result;
-
- VECCOPY(ray_end, ray_normal_local);
- VecMulf(ray_end, 2000);
- VecAddf(ray_end, ray_start_local, ray_end);
-
- result = LineIntersectLine(verts[e->v1].co, verts[e->v2].co, ray_start_local, ray_end, intersect, dvec); /* dvec used but we don't care about result */
-
- if (result)
- {
- float edge_loc[3], vec[3];
- float mul;
-
- /* check for behind ray_start */
- VecSubf(dvec, intersect, ray_start_local);
-
- VecSubf(edge_loc, verts[e->v1].co, verts[e->v2].co);
- VecSubf(vec, intersect, verts[e->v2].co);
-
- mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc);
-
- if (mul > 1) {
- mul = 1;
- VECCOPY(intersect, verts[e->v1].co);
- }
- else if (mul < 0) {
- mul = 0;
- VECCOPY(intersect, verts[e->v2].co);
- }
-
- if (Inpf(ray_normal_local, dvec) > 0)
- {
- float location[3];
- float new_depth;
- int screen_loc[2];
- int new_dist;
-
- VECCOPY(location, intersect);
-
- Mat4MulVecfl(obmat, location);
-
- new_depth = VecLenf(location, ray_start);
-
- project_int(t->ar, location, screen_loc);
- new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
-
- if (new_dist <= *dist && new_depth < *depth)
- {
- float n1[3], n2[3];
-
- *depth = new_depth;
- retval = 1;
-
- VecSubf(edge_loc, verts[e->v1].co, verts[e->v2].co);
- VecSubf(vec, intersect, verts[e->v2].co);
-
- mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc);
-
- NormalShortToFloat(n1, verts[e->v1].no);
- NormalShortToFloat(n2, verts[e->v2].no);
- VecLerpf(no, n2, n1, mul);
- Normalize(no);
-
- VECCOPY(loc, location);
-
- Mat3MulVecfl(timat, no);
- Normalize(no);
-
- *dist = new_dist;
- }
- }
- }
+ retval |= snapEdge(t, verts[e->v1].co, verts[e->v1].no, verts[e->v2].co, verts[e->v2].no, mval, ray_start, ray_start_local, ray_normal_local, obmat, timat, loc, no, dist, depth);
}
}
@@ -1169,7 +1313,44 @@ int snapDerivedMesh(TransInfo *t, Object *ob, DerivedMesh *dm, EditMesh *em, flo
return retval;
}
-int snapObjects(TransInfo *t, int *dist, float *loc, float *no, int mode) {
+int snapObject(TransInfo *t, Object *ob, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth)
+{
+ int editobject = 0;
+ int retval = 0;
+
+ if (ob == t->obedit)
+ {
+ editobject = 1;
+ }
+
+ if (ob->type == OB_MESH) {
+ EditMesh *em;
+ DerivedMesh *dm;
+
+ if (editobject)
+ {
+ em = ((Mesh *)ob->data)->edit_mesh;
+ dm = editmesh_get_derived_cage(t->scene, t->obedit, em, CD_MASK_BAREMESH);
+ }
+ else
+ {
+ em = NULL;
+ dm = mesh_get_derived_final(t->scene, ob, CD_MASK_BAREMESH);
+ }
+
+ retval = snapDerivedMesh(t, ob, dm, em, obmat, ray_start, ray_normal, mval, loc, no, dist, depth);
+
+ dm->release(dm);
+ }
+ else if (ob->type == OB_ARMATURE)
+ {
+ retval = snapArmature(t, ob, ob->data, obmat, ray_start, ray_normal, mval, loc, no, dist, depth);
+ }
+
+ return retval;
+}
+
+int snapObjects(TransInfo *t, int *dist, float *loc, float *no, SnapMode mode) {
Scene *scene = t->scene;
View3D *v3d = t->view;
Base *base;
@@ -1181,23 +1362,215 @@ int snapObjects(TransInfo *t, int *dist, float *loc, float *no, int mode) {
if (mode == SNAP_ALL && t->obedit)
{
- DerivedMesh *dm;
Object *ob = t->obedit;
- EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
- dm = editmesh_get_derived_cage(t->scene, t->obedit, em, CD_MASK_BAREMESH);
+ retval |= snapObject(t, ob, ob->obmat, ray_start, ray_normal, t->mval, loc, no, dist, &depth);
+ }
+
+ base= FIRSTBASE;
+ for ( base = FIRSTBASE; base != NULL; base = base->next ) {
+ if ( BASE_SELECTABLE(v3d, base) && (base->flag & (BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA)) == 0 && ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT|BA_WAS_SEL)) == 0) || (mode == SNAP_NOT_OBEDIT && base != BASACT)) ) {
+ Object *ob = base->object;
+
+ if (ob->transflag & OB_DUPLI)
+ {
+ DupliObject *dupli_ob;
+ ListBase *lb = object_duplilist(t->scene, ob);
+
+ for(dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next)
+ {
+ Object *ob = dupli_ob->ob;
+
+ retval |= snapObject(t, ob, dupli_ob->mat, ray_start, ray_normal, t->mval, loc, no, dist, &depth);
+ }
+
+ free_object_duplilist(lb);
+ }
+
+ retval |= snapObject(t, ob, ob->obmat, ray_start, ray_normal, t->mval, loc, no, dist, &depth);
+ }
+ }
+
+ return retval;
+}
+
+/******************** PEELING *********************************/
+
+
+int cmpPeel(void *arg1, void *arg2)
+{
+ DepthPeel *p1 = arg1;
+ DepthPeel *p2 = arg2;
+ int val = 0;
+
+ if (p1->depth < p2->depth)
+ {
+ val = -1;
+ }
+ else if (p1->depth > p2->depth)
+ {
+ val = 1;
+ }
+
+ return val;
+}
+
+void removeDoublesPeel(ListBase *depth_peels)
+{
+ DepthPeel *peel;
+
+ for (peel = depth_peels->first; peel; peel = peel->next)
+ {
+ DepthPeel *next_peel = peel->next;
- retval = snapDerivedMesh(t, ob, dm, em, ob->obmat, ray_start, ray_normal, t->mval, loc, no, dist, &depth);
+ if (peel && next_peel && ABS(peel->depth - next_peel->depth) < 0.0015)
+ {
+ peel->next = next_peel->next;
+
+ if (next_peel->next)
+ {
+ next_peel->next->prev = peel;
+ }
+
+ MEM_freeN(next_peel);
+ }
+ }
+}
+
+void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float no[3], Object *ob)
+{
+ DepthPeel *peel = MEM_callocN(sizeof(DepthPeel), "DepthPeel");
+
+ peel->depth = depth;
+ peel->ob = ob;
+ VECCOPY(peel->p, p);
+ VECCOPY(peel->no, no);
+
+ BLI_addtail(depth_peels, peel);
+
+ peel->flag = 0;
+}
+
+int peelDerivedMesh(TransInfo *t, Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], ListBase *depth_peels)
+{
+ int retval = 0;
+ int totvert = dm->getNumVerts(dm);
+ int totface = dm->getNumFaces(dm);
+
+ if (totvert > 0) {
+ float imat[4][4];
+ float timat[3][3]; /* transpose inverse matrix for normals */
+ float ray_start_local[3], ray_normal_local[3];
+ int test = 1;
+
+ Mat4Invert(imat, obmat);
+
+ Mat3CpyMat4(timat, imat);
+ Mat3Transp(timat);
- dm->release(dm);
+ VECCOPY(ray_start_local, ray_start);
+ VECCOPY(ray_normal_local, ray_normal);
+
+ Mat4MulVecfl(imat, ray_start_local);
+ Mat4Mul3Vecfl(imat, ray_normal_local);
+
+
+ /* If number of vert is more than an arbitrary limit,
+ * test against boundbox first
+ * */
+ if (totface > 16) {
+ struct BoundBox *bb = object_get_boundbox(ob);
+ test = ray_hit_boundbox(bb, ray_start_local, ray_normal_local);
+ }
+
+ if (test == 1) {
+ MVert *verts = dm->getVertArray(dm);
+ MFace *faces = dm->getFaceArray(dm);
+ int i;
+
+ for( i = 0; i < totface; i++) {
+ MFace *f = faces + i;
+ float lambda;
+ int result;
+
+
+ result = RayIntersectsTriangleThreshold(ray_start_local, ray_normal_local, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, &lambda, NULL, 0.001);
+
+ if (result) {
+ float location[3], normal[3];
+ float intersect[3];
+ float new_depth;
+
+ VECCOPY(intersect, ray_normal_local);
+ VecMulf(intersect, lambda);
+ VecAddf(intersect, intersect, ray_start_local);
+
+ VECCOPY(location, intersect);
+
+ if (f->v4)
+ CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal);
+ else
+ CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal);
+
+ Mat4MulVecfl(obmat, location);
+
+ new_depth = VecLenf(location, ray_start);
+
+ Mat3MulVecfl(timat, normal);
+ Normalize(normal);
+
+ addDepthPeel(depth_peels, new_depth, location, normal, ob);
+ }
+
+ if (f->v4 && result == 0)
+ {
+ result = RayIntersectsTriangleThreshold(ray_start_local, ray_normal_local, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, &lambda, NULL, 0.001);
+
+ if (result) {
+ float location[3], normal[3];
+ float intersect[3];
+ float new_depth;
+
+ VECCOPY(intersect, ray_normal_local);
+ VecMulf(intersect, lambda);
+ VecAddf(intersect, intersect, ray_start_local);
+
+ VECCOPY(location, intersect);
+
+ if (f->v4)
+ CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal);
+ else
+ CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal);
+
+ Mat4MulVecfl(obmat, location);
+
+ new_depth = VecLenf(location, ray_start);
+
+ Mat3MulVecfl(timat, normal);
+ Normalize(normal);
+
+ addDepthPeel(depth_peels, new_depth, location, normal, ob);
+ }
+ }
+ }
+ }
}
+
+ return retval;
+}
+
+int peelObjects(TransInfo *t, ListBase *depth_peels, short mval[2])
+{
+ Scene *scene= t->scene;
+ View3D *v3d= t->view;
+ Base *base;
+ int retval = 0;
+ float ray_start[3], ray_normal[3];
+ viewray(t->ar, v3d, t->mval, ray_start, ray_normal);
+
for ( base = scene->base.first; base != NULL; base = base->next ) {
- if ( BASE_SELECTABLE(v3d, base) && /* SELECTABLE */
- (base->flag & (BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA)) == 0 && /* IS NOT AFFECTED BY TRANSFORM */
- ( (mode == SNAP_NOT_SELECTED && (base->flag & (SELECT|BA_WAS_SEL)) == 0) || /* NOT_SELECTED */
- ((mode == SNAP_NOT_OBEDIT || mode == SNAP_ALL) && base->object != t->obedit)) /* OR NOT OBEDIT */
- ) {
+ if ( BASE_SELECTABLE(v3d, base) ) {
Object *ob = base->object;
if (ob->transflag & OB_DUPLI)
@@ -1211,21 +1584,9 @@ int snapObjects(TransInfo *t, int *dist, float *loc, float *no, int mode) {
if (ob->type == OB_MESH) {
DerivedMesh *dm;
- EditMesh *em;
int val;
-
- if(ob == t->obedit)
- {
- em = ((Mesh *)ob->data)->edit_mesh;
- dm = editmesh_get_derived_cage(t->scene, t->obedit, em, CD_MASK_BAREMESH);
- }
- else
- {
- em = NULL;
- dm = mesh_get_derived_final(t->scene, ob, CD_MASK_BAREMESH);
- }
-
- val = snapDerivedMesh(t, ob, dm, em, dupli_ob->mat, ray_start, ray_normal, t->mval, loc, no, dist, &depth);
+
+ val = peelDerivedMesh(t, ob, dm, dupli_ob->mat, ray_start, ray_normal, mval, depth_peels);
retval = retval || val;
@@ -1237,11 +1598,24 @@ int snapObjects(TransInfo *t, int *dist, float *loc, float *no, int mode) {
}
if (ob->type == OB_MESH) {
- DerivedMesh *dm = mesh_get_derived_final(t->scene, ob, CD_MASK_BAREMESH);
+ EditMesh *em;
+ DerivedMesh *dm = NULL;
int val;
-
- val = snapDerivedMesh(t, ob, dm, NULL, ob->obmat, ray_start, ray_normal, t->mval, loc, no, dist, &depth);
-
+
+ if (ob != t->obedit)
+ {
+ dm = mesh_get_derived_final(t->scene, ob, CD_MASK_BAREMESH);
+
+ val = peelDerivedMesh(t, ob, dm, ob->obmat, ray_start, ray_normal, mval, depth_peels);
+ }
+ else
+ {
+ em = ((Mesh *)ob->data)->edit_mesh;
+ dm = editmesh_get_derived_cage(t->scene, t->obedit, em, CD_MASK_BAREMESH);
+
+ val = peelDerivedMesh(t, ob, dm, ob->obmat, ray_start, ray_normal, mval, depth_peels);
+ }
+
retval = retval || val;
dm->release(dm);
@@ -1249,6 +1623,9 @@ int snapObjects(TransInfo *t, int *dist, float *loc, float *no, int mode) {
}
}
+ BLI_sortlist(depth_peels, cmpPeel);
+ removeDoublesPeel(depth_peels);
+
return retval;
}
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 9686d4d6094..34c9dd23b18 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -373,6 +373,45 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac
}
}
+static void draw_uvs_other(SpaceImage *sima, Scene *scene, Object *obedit, MTFace *activetf)
+{
+ Base *base;
+ Image *curimage;
+
+ curimage= (activetf)? activetf->tpage: NULL;
+
+ glColor3ub(96, 96, 96);
+
+ for(base=scene->base.first; base; base=base->next) {
+ Object *ob= base->object;
+
+ if(!(base->flag & SELECT)) continue;
+ if(!(base->lay & scene->lay)) continue;
+ if(ob->restrictflag & OB_RESTRICT_VIEW) continue;
+
+ if((ob->type==OB_MESH) && (ob!=obedit)) {
+ Mesh *me= ob->data;
+
+ if(me->mtface) {
+ MFace *mface= me->mface;
+ MTFace *tface= me->mtface;
+ int a;
+
+ for(a=me->totface; a>0; a--, tface++, mface++) {
+ if(tface->tpage == curimage) {
+ glBegin(GL_LINE_LOOP);
+ glVertex2fv(tface->uv[0]);
+ glVertex2fv(tface->uv[1]);
+ glVertex2fv(tface->uv[2]);
+ if(mface->v4) glVertex2fv(tface->uv[3]);
+ glEnd();
+ }
+ }
+ }
+ }
+ }
+}
+
/* draws uv's in the image space */
static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
{
@@ -397,6 +436,10 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
interpedges= (scene->selectmode & SCE_SELECT_VERTEX);
else
interpedges= (settings->uv_selectmode == UV_SELECT_VERTEX);
+
+ /* draw other uvs */
+ if(sima->flag & SI_DRAW_OTHER)
+ draw_uvs_other(sima, scene, obedit, activetf);
/* 1. draw shadow mesh */
@@ -576,7 +619,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
}
glLineWidth(1);
- col2[0] = col2[1] = col2[2] = 128; col2[3] = 255;
+ col2[0] = col2[1] = col2[2] = 192; col2[3] = 255;
glColor4ubv((unsigned char *)col2);
if(me->drawflag & ME_DRAWEDGES) {
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
index e326be9d776..ce130951840 100644
--- a/source/blender/gpu/GPU_draw.h
+++ b/source/blender/gpu/GPU_draw.h
@@ -84,7 +84,7 @@ int GPU_set_tpage(struct MTFace *tface);
int GPU_default_lights(void);
int GPU_scene_object_lights(struct Scene *scene, struct Object *ob,
- int lay, float viewmat[][4]);
+ int lay, float viewmat[][4], int ortho);
/* Text render
* - based on moving uv coordinates */
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 6f69a2b8a31..7f5f85e23a6 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -167,6 +167,8 @@ static int smaller_pow2(int num)
static int is_pow2_limit(int num)
{
/* take texture clamping into account */
+ if (G.f & G_TEXTUREPAINT)
+ return 1;
if (U.glreslimit != 0 && num > U.glreslimit)
return 0;
@@ -175,6 +177,9 @@ static int is_pow2_limit(int num)
static int smaller_pow2_limit(int num)
{
+ if (G.f & G_TEXTUREPAINT)
+ return 1;
+
/* take texture clamping into account */
if (U.glreslimit != 0 && num > U.glreslimit)
return U.glreslimit;
@@ -999,6 +1004,8 @@ int GPU_default_lights(void)
U.light[2].spec[3]= 1.0;
}
+ glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
+
glLightfv(GL_LIGHT0, GL_POSITION, U.light[0].vec);
glLightfv(GL_LIGHT0, GL_DIFFUSE, U.light[0].col);
glLightfv(GL_LIGHT0, GL_SPECULAR, U.light[0].spec);
@@ -1036,7 +1043,7 @@ int GPU_default_lights(void)
return count;
}
-int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4])
+int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4], int ortho)
{
Base *base;
Lamp *la;
@@ -1047,6 +1054,10 @@ int GPU_scene_object_lights(Scene *scene, Object *ob, int lay, float viewmat[][4
for(count=0; count<8; count++)
glDisable(GL_LIGHT0+count);
+ /* view direction for specular is not compute correct by default in
+ * opengl, so we set the settings ourselfs */
+ glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (ortho)? GL_FALSE: GL_TRUE);
+
count= 0;
for(base=scene->base.first; base; base=base->next) {
@@ -1133,9 +1144,6 @@ void GPU_state_init(void)
GPU_default_lights();
- /* no local viewer, looks ugly in ortho mode */
- /* glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, &one); */
-
glDepthFunc(GL_LEQUAL);
/* scaling matrices */
glEnable(GL_NORMALIZE);
diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt
index 61ec3430bff..391f6e9e1a2 100644
--- a/source/blender/imbuf/CMakeLists.txt
+++ b/source/blender/imbuf/CMakeLists.txt
@@ -33,12 +33,17 @@ SET(INC
${PNG_INC}
${TIFF_INC}
${ZLIB_INC}
+ ${OPENJPEG_INC}
)
IF(WITH_OPENEXR)
ADD_DEFINITIONS(-DWITH_OPENEXR)
ENDIF(WITH_OPENEXR)
+IF(WITH_OPENJPEG)
+ ADD_DEFINITIONS(-DWITH_OPENJPEG)
+ENDIF(WITH_OPENJPEG)
+
IF(WITH_QUICKTIME)
SET(INC ${INC} ${QUICKTIME_INC})
ADD_DEFINITIONS(-DWITH_QUICKTIME)
diff --git a/source/blender/imbuf/intern/Makefile b/source/blender/imbuf/intern/Makefile
index 8294931b60f..427052cbdc3 100644
--- a/source/blender/imbuf/intern/Makefile
+++ b/source/blender/imbuf/intern/Makefile
@@ -48,6 +48,10 @@ ifeq ($(WITH_DDS), true)
CPPFLAGS += -DWITH_DDS
endif
+ifeq ($(WITH_OPENJPEG), true)
+ CFLAGS += -DWITH_OPENJPEG -I../../../../extern/libopenjpeg
+endif
+
CFLAGS += $(LEVEL_1_C_WARNINGS)
CPPFLAGS += -I$(NAN_JPEG)/include
diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c
index 8b7ef8c8101..45f23d34405 100644
--- a/source/blender/imbuf/intern/cineon/cineon_dpx.c
+++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c
@@ -40,6 +40,8 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
+#include "BKE_global.h"
+
#include "MEM_guardedalloc.h"
static void cineon_conversion_parameters(LogImageByteConversionParameters *params)
@@ -58,7 +60,6 @@ static void cineon_conversion_parameters(LogImageByteConversionParameters *param
static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int size, int flags)
{
- LogImageByteConversionParameters conversion;
ImBuf *ibuf;
LogImageFile *image;
int x, y;
@@ -66,7 +67,7 @@ static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int
int width, height, depth;
float *frow;
- cineon_conversion_parameters(&conversion);
+ logImageSetVerbose((G.f & G_DEBUG) ? 1:0);
image = logImageOpenFromMem(mem, size, use_cineon);
@@ -87,15 +88,13 @@ static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int
return NULL;
}
- logImageSetByteConversion(image, &conversion);
-
ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat | flags, 0);
row = MEM_mallocN(sizeof(unsigned short)*width*depth, "row in cineon_dpx.c");
frow = ibuf->rect_float+width*height*4;
for (y = 0; y < height; y++) {
- logImageGetRowBytes(image, row, y);
+ logImageGetRowBytes(image, row, y); /* checks image->params.doLogarithm and convert */
upix = row;
frow -= width*4;
@@ -145,7 +144,7 @@ static int imb_save_dpx_cineon(ImBuf *buf, char *filename, int use_cineon, int f
}
}
- logImageSetVerbose(0);
+ logImageSetVerbose((G.f & G_DEBUG) ? 1:0);
logImage = logImageCreate(filename, use_cineon, width, height, depth);
if (!logImage) return 0;
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index 7314e82a132..8459eb0f989 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -477,19 +477,49 @@ intern_dpxOpen(int mode, const char* bytestuff, int bufsize) {
logImageGetByteConversionDefaults(&dpx->params);
/* The SMPTE define this code:
+ * 0 - User-defined
+ * 1 - Printing density
* 2 - Linear
* 3 - Logarithmic
+ * 4 - Unspecified video
+ * 5 - SMPTE 240M
+ * 6 - CCIR 709-1
+ * 7 - CCIR 601-2 system B or G
+ * 8 - CCIR 601-2 system M
+ * 9 - NTSC composite video
+ * 10 - PAL composite video
+ * 11 - Z linear
+ * 12 - homogeneous
*
* Note that transfer_characteristics is U8, don't need
* check the byte order.
*/
+
switch (header.imageInfo.channel[0].transfer_characteristics) {
- case 2:
+ case 1:
+ case 2: /* linear */
dpx->params.doLogarithm= 0;
break;
+
case 3:
dpx->params.doLogarithm= 1;
break;
+
+ /* TODO - Unsupported, but for now just load them,
+ * colors may look wrong, but can solve color conversion later
+ */
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ case 12:
+ if (verbose) d_printf("Un-supported Transfer Characteristics: %d using linear color conversion\n", header.imageInfo.channel[0].transfer_characteristics);
+ dpx->params.doLogarithm= 0;
+ break;
default:
if (verbose) d_printf("Un-supported Transfer Characteristics: %d\n", header.imageInfo.channel[0].transfer_characteristics);
dpxClose(dpx);
diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c
index b4e384ada72..d00e34cfdbe 100644
--- a/source/blender/imbuf/intern/radiance_hdr.c
+++ b/source/blender/imbuf/intern/radiance_hdr.c
@@ -180,7 +180,6 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags)
int width=0, height=0;
int x, y;
unsigned char* ptr;
- unsigned char* rect;
char oriY[80], oriX[80];
if (imb_is_a_hdr((void*)mem))
@@ -201,7 +200,7 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags)
ptr++;
if (flags & IB_test) ibuf = IMB_allocImBuf(width, height, 32, 0, 0);
- else ibuf = IMB_allocImBuf(width, height, 32, IB_rect|IB_rectfloat, 0);
+ else ibuf = IMB_allocImBuf(width, height, 32, (flags & IB_rect)|IB_rectfloat, 0);
if (ibuf==NULL) return NULL;
ibuf->ftype = RADHDR;
@@ -211,7 +210,6 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags)
/* read in and decode the actual data */
sline = (RGBE*)MEM_mallocN(sizeof(RGBE)*width, "radhdr_read_tmpscan");
- rect = (unsigned char*)ibuf->rect;
rect_float = (float *)ibuf->rect_float;
for (y=0;y<height;y++) {
@@ -228,19 +226,15 @@ struct ImBuf *imb_loadhdr(unsigned char *mem, int size, int flags)
*rect_float++ = fcol[GRN];
*rect_float++ = fcol[BLU];
*rect_float++ = 1.0f;
- /* Also old oldstyle for the rest of blender which is not using floats yet */
- // e: changed to simpler tonemapping, previous code was rather slow (is this actually still relevant at all?)
- fcol[RED] = fcol[RED]/(1.f + fcol[RED]);
- fcol[GRN] = fcol[GRN]/(1.f + fcol[GRN]);
- fcol[BLU] = fcol[BLU]/(1.f + fcol[BLU]);
- *rect++ = (unsigned char)((fcol[RED] < 0.f) ? 0 : ((fcol[RED] > 1.f) ? 255 : (255.f*fcol[RED])));
- *rect++ = (unsigned char)((fcol[GRN] < 0.f) ? 0 : ((fcol[GRN] > 1.f) ? 255 : (255.f*fcol[GRN])));
- *rect++ = (unsigned char)((fcol[BLU] < 0.f) ? 0 : ((fcol[BLU] > 1.f) ? 255 : (255.f*fcol[BLU])));
- *rect++ = 255;
}
}
MEM_freeN(sline);
if (oriY[0]=='-') IMB_flipy(ibuf);
+
+ if (flags & IB_rect) {
+ IMB_rect_from_float(ibuf);
+ }
+
return ibuf;
}
//else printf("Data not found!\n");
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index d8b5c206ecf..f8ea5f95d65 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -263,7 +263,7 @@ typedef struct Curve {
/* *************** BEZTRIPLE **************** */
/* h1 h2 (beztriple) */
-enum {
+typedef enum eBezTriple_Handle {
HD_FREE = 0,
HD_AUTO,
HD_VECT,
@@ -272,7 +272,7 @@ enum {
} eBezTriple_Handle;
/* interpolation modes (used only for BezTriple->ipo) */
-enum {
+typedef enum eBezTriple_Interpolation {
BEZT_IPO_CONST = 0, /* constant interpolation */
BEZT_IPO_LIN, /* linear interpolation */
BEZT_IPO_BEZ, /* bezier interpolation */
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 6826329627b..64e335fb3ad 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -427,6 +427,12 @@ extern Object workob;
/* ob->gameflag2 */
#define OB_NEVER_DO_ACTIVITY_CULLING 1
+#define OB_LOCK_RIGID_BODY_X_AXIS 4
+#define OB_LOCK_RIGID_BODY_Y_AXIS 8
+#define OB_LOCK_RIGID_BODY_Z_AXIS 16
+#define OB_LOCK_RIGID_BODY_X_ROT_AXIS 32
+#define OB_LOCK_RIGID_BODY_Y_ROT_AXIS 64
+#define OB_LOCK_RIGID_BODY_Z_ROT_AXIS 128
#define OB_LIFE (OB_PROP|OB_DYNAMIC|OB_ACTOR|OB_MAINACTOR|OB_CHILD)
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 067e3d0c2d0..d5828f7e3a3 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -502,12 +502,21 @@ typedef struct ToolSettings {
char skgen_postpro_passes;
char skgen_subdivisions[3];
char skgen_multi_level;
- char skgen_optimisation_method;
-
- char tpad[2];
-
+ int skgen_pad;
+
+ /* Skeleton Sketching */
+ struct Object *skgen_template;
+ char bone_sketching;
+ char bone_sketching_convert;
+ char skgen_subdivision_number;
+ char skgen_retarget_options;
+ char skgen_retarget_roll;
+ char skgen_side_string[8];
+ char skgen_num_string[8];
+
/* Alt+RMB option */
char edge_mode;
+ char pad3[2];
} ToolSettings;
typedef struct bStats {
@@ -775,6 +784,7 @@ typedef struct Scene {
/* scene->snap_flag */
#define SCE_SNAP 1
#define SCE_SNAP_ROTATE 2
+#define SCE_SNAP_PEEL_OBJECT 4
/* scene->snap_target */
#define SCE_SNAP_TARGET_CLOSEST 0
#define SCE_SNAP_TARGET_CENTER 1
@@ -784,6 +794,7 @@ typedef struct Scene {
#define SCE_SNAP_MODE_VERTEX 0
#define SCE_SNAP_MODE_EDGE 1
#define SCE_SNAP_MODE_FACE 2
+#define SCE_SNAP_MODE_VOLUME 3
/* sce->selectmode */
#define SCE_SELECT_VERTEX 1 /* for mesh */
@@ -933,6 +944,25 @@ typedef enum SculptFlags {
#define SKGEN_AVERAGE 1
#define SKGEN_SHARPEN 2
+/* toolsettings->bone_sketching */
+#define BONE_SKETCHING 1
+#define BONE_SKETCHING_QUICK 2
+#define BONE_SKETCHING_ADJUST 4
+
+/* toolsettings->bone_sketching_convert */
+#define SK_CONVERT_CUT_FIXED 0
+#define SK_CONVERT_CUT_LENGTH 1
+#define SK_CONVERT_CUT_ADAPTATIVE 2
+#define SK_CONVERT_RETARGET 3
+
+/* toolsettings->skgen_retarget_options */
+#define SK_RETARGET_AUTONAME 1
+
+/* toolsettings->skgen_retarget_roll */
+#define SK_RETARGET_ROLL_VIEW 1
+#define SK_RETARGET_ROLL_JOINT 2
+
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesdna/DNA_sensor_types.h b/source/blender/makesdna/DNA_sensor_types.h
index d8a1ffc6c24..2cae2cc8ccb 100644
--- a/source/blender/makesdna/DNA_sensor_types.h
+++ b/source/blender/makesdna/DNA_sensor_types.h
@@ -238,6 +238,7 @@ typedef struct bJoystickSensor {
* */
/* #define SENS_COLLISION_PROPERTY 0 */
#define SENS_COLLISION_MATERIAL 1
+#define SENS_COLLISION_PULSE 2
/* ray specific mode */
/* X-Ray means that the ray will traverse objects that don't have the property/material */
#define SENS_RAY_XRAY 2
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 686119f77fa..d4dffddcdcc 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -580,6 +580,7 @@ typedef struct SpaceImaSel {
#define SI_SMOOTH_UV 1<<20
#define SI_DRAW_STRETCH 1<<21
#define SI_DISPGP 1<<22
+#define SI_DRAW_OTHER 1<<23
/* SpaceIpo->flag (Graph Editor Settings) */
#define SIPO_LOCK_VIEW (1<<0)
diff --git a/source/blender/nodes/TEX_node.h b/source/blender/nodes/TEX_node.h
index 40cb65eacce..c52fc757507 100644
--- a/source/blender/nodes/TEX_node.h
+++ b/source/blender/nodes/TEX_node.h
@@ -41,6 +41,7 @@
extern bNodeType tex_node_math;
extern bNodeType tex_node_mix_rgb;
extern bNodeType tex_node_valtorgb;
+extern bNodeType tex_node_valtonor;
extern bNodeType tex_node_rgbtobw;
extern bNodeType tex_node_output;
extern bNodeType tex_node_viewer;
@@ -57,6 +58,10 @@ extern bNodeType tex_node_distance;
extern bNodeType tex_node_rotate;
extern bNodeType tex_node_translate;
+extern bNodeType tex_node_scale;
+
+extern bNodeType tex_node_compose;
+extern bNodeType tex_node_decompose;
extern bNodeType tex_node_proc_voronoi;
extern bNodeType tex_node_proc_blend;
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_blur.c b/source/blender/nodes/intern/CMP_nodes/CMP_blur.c
index 2c7974d129d..a96f3489978 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_blur.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_blur.c
@@ -567,6 +567,11 @@ static void node_composit_exec_blur(void *data, bNode *node, bNodeStack **in, bN
if(out[0]->hasoutput==0) return;
+ if(nbd->relative) {
+ nbd->sizex= (int)(nbd->percentx*nbd->image_in_width);
+ nbd->sizey= (int)(nbd->percenty*nbd->image_in_height);
+ }
+
if (((NodeBlurData *)node->storage)->filtertype == R_FILTER_FAST_GAUSS) {
CompBuf *new, *img = in[0]->data;
/*from eeshlo's original patch, removed to fit in with the existing blur node */
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_compose.c b/source/blender/nodes/intern/TEX_nodes/TEX_compose.c
new file mode 100644
index 00000000000..26576befa3e
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_compose.c
@@ -0,0 +1,71 @@
+/**
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+
+static bNodeSocketType inputs[]= {
+ { SOCK_VALUE, 1, "Red", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f },
+ { SOCK_VALUE, 1, "Green", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f },
+ { SOCK_VALUE, 1, "Blue", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f },
+ { SOCK_VALUE, 1, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
+};
+static bNodeSocketType outputs[]= {
+ { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
+};
+
+static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ int i;
+ for(i = 0; i < 4; i++)
+ out[i] = tex_input_value(in[i], coord, thread);
+}
+
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &colorfn);
+}
+
+bNodeType tex_node_compose= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_COMPOSE,
+ /* name */ "Compose RGBA",
+ /* width+range */ 100, 60, 150,
+ /* class+opts */ NODE_CLASS_OP_COLOR, 0,
+ /* input sock */ inputs,
+ /* output sock */ outputs,
+ /* storage */ "",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+
+};
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_decompose.c b/source/blender/nodes/intern/TEX_nodes/TEX_decompose.c
new file mode 100644
index 00000000000..c08eb12a18f
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_decompose.c
@@ -0,0 +1,92 @@
+/**
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+#include <math.h>
+
+static bNodeSocketType inputs[]= {
+ { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
+};
+static bNodeSocketType outputs[]= {
+ { SOCK_VALUE, 0, "Red", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f },
+ { SOCK_VALUE, 0, "Green", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f },
+ { SOCK_VALUE, 0, "Blue", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f },
+ { SOCK_VALUE, 0, "Alpha", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
+};
+
+static void valuefn_r(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ tex_input_rgba(out, in[0], coord, thread);
+ *out = out[0];
+}
+
+static void valuefn_g(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ tex_input_rgba(out, in[0], coord, thread);
+ *out = out[1];
+}
+
+static void valuefn_b(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ tex_input_rgba(out, in[0], coord, thread);
+ *out = out[2];
+}
+
+static void valuefn_a(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ tex_input_rgba(out, in[0], coord, thread);
+ *out = out[3];
+}
+
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &valuefn_r);
+ tex_output(node, in, out[1], &valuefn_g);
+ tex_output(node, in, out[2], &valuefn_b);
+ tex_output(node, in, out[3], &valuefn_a);
+}
+
+bNodeType tex_node_decompose= {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_DECOMPOSE,
+ /* name */ "Decompose RGBA",
+ /* width+range */ 100, 60, 150,
+ /* class+opts */ NODE_CLASS_OP_COLOR, 0,
+ /* input sock */ inputs,
+ /* output sock */ outputs,
+ /* storage */ "",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+
+};
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c b/source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c
index d1a33896fc3..bb1a49fb235 100644
--- a/source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_hueSatVal.c
@@ -30,16 +30,16 @@
static bNodeSocketType inputs[]= {
- { SOCK_VALUE, 1, "Hue", 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_VALUE, 1, "Saturation", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f},
- { SOCK_VALUE, 1, "Value", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f},
- { SOCK_VALUE, 1, "Fac", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 1, "Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
- { -1, 0, "" }
+ { SOCK_VALUE, 1, "Hue", 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f },
+ { SOCK_VALUE, 1, "Saturation", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f },
+ { SOCK_VALUE, 1, "Value", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f },
+ { SOCK_VALUE, 1, "Factor", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f },
+ { SOCK_RGBA, 1, "Color", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
};
static bNodeSocketType outputs[]= {
- { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
- { -1, 0, "" }
+ { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
};
static void do_hue_sat_fac(bNode *node, float *out, float hue, float sat, float val, float *in, float fac)
@@ -67,15 +67,19 @@ static void do_hue_sat_fac(bNode *node, float *out, float hue, float sat, float
static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
{
- float in0 = tex_input_value(in[0], coord, thread);
- float in1 = tex_input_value(in[1], coord, thread);
- float in2 = tex_input_value(in[2], coord, thread);
- float in3 = tex_input_value(in[3], coord, thread);
+ float hue = tex_input_value(in[0], coord, thread);
+ float sat = tex_input_value(in[1], coord, thread);
+ float val = tex_input_value(in[2], coord, thread);
+ float fac = tex_input_value(in[3], coord, thread);
- float in4[4];
- tex_input_rgba(in4, in[4], coord, thread);
+ float col[4];
+ tex_input_rgba(col, in[4], coord, thread);
- do_hue_sat_fac(node, out, in0, in1, in2, in4, in3);
+ hue += 0.5f; /* [-.5, .5] -> [0, 1] */
+
+ do_hue_sat_fac(node, out, hue, sat, val, col, fac);
+
+ out[3] = col[3];
}
static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_math.c b/source/blender/nodes/intern/TEX_nodes/TEX_math.c
index a2c66078692..bac91fc0901 100644
--- a/source/blender/nodes/intern/TEX_nodes/TEX_math.c
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_math.c
@@ -143,6 +143,29 @@ static void valuefn(float *out, float *coord, bNode *node, bNodeStack **in, shor
*out= (int)(in0 + 0.5f);
}
break;
+
+ case 15: /* Less Than */
+ {
+ if( in0 < in1 )
+ *out= 1.0f;
+ else
+ *out= 0.0f;
+ }
+ break;
+
+ case 16: /* Greater Than */
+ {
+ if( in0 > in1 )
+ *out= 1.0f;
+ else
+ *out= 0.0f;
+ }
+ break;
+
+ default:
+ fprintf(stderr,
+ "%s:%d: unhandeld value in switch statement: %d\n",
+ __FILE__, __LINE__, node->custom1);
}
}
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_proc.c b/source/blender/nodes/intern/TEX_nodes/TEX_proc.c
index 9078dd1be21..ec65cf186a8 100644
--- a/source/blender/nodes/intern/TEX_nodes/TEX_proc.c
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_proc.c
@@ -110,25 +110,25 @@ static int count_outputs(bNode *node)
/* Boilerplate generators */
#define ProcNoInputs(name) \
- static void name##_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread) \
- {}
+ static void name##_map_inputs(Tex *tex, bNodeStack **in, float *coord, short thread) \
+ {}
#define ProcDef(name) \
- static void name##_colorfn(float *result, float *coord, bNode *node, bNodeStack **in, short thread) \
- { \
- texfn(result, coord, node, in, 0, &name##_map_inputs, thread); \
- } \
- static void name##_normalfn(float *result, float *coord, bNode *node, bNodeStack **in, short thread) \
- { \
- texfn(result, coord, node, in, 1, &name##_map_inputs, thread); \
- } \
- static void name##_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) \
- { \
- int outs = count_outputs(node); \
- if(outs >= 1) tex_output(node, in, out[0], &name##_colorfn); \
- if(outs >= 2) tex_output(node, in, out[1], &name##_normalfn); \
- if(outs >= 1) tex_do_preview(node, out[0], data); \
- }
+ static void name##_colorfn(float *result, float *coord, bNode *node, bNodeStack **in, short thread) \
+ { \
+ texfn(result, coord, node, in, 0, &name##_map_inputs, thread); \
+ } \
+ static void name##_normalfn(float *result, float *coord, bNode *node, bNodeStack **in, short thread) \
+ { \
+ texfn(result, coord, node, in, 1, &name##_map_inputs, thread); \
+ } \
+ static void name##_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out) \
+ { \
+ int outs = count_outputs(node); \
+ if(outs >= 1) tex_output(node, in, out[0], &name##_colorfn); \
+ if(outs >= 2) tex_output(node, in, out[1], &name##_normalfn); \
+ if(outs >= 1) tex_do_preview(node, out[0], data); \
+ }
/* --- VORONOI -- */
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c b/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c
index 93bf17d4862..3a2c2b1def1 100644
--- a/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_rotate.c
@@ -91,8 +91,6 @@ static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, shor
static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
tex_output(node, in, out[0], &colorfn);
-
- tex_do_preview(node, out[0], data);
}
bNodeType tex_node_rotate= {
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_scale.c b/source/blender/nodes/intern/TEX_nodes/TEX_scale.c
new file mode 100644
index 00000000000..792c3468e9f
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_scale.c
@@ -0,0 +1,76 @@
+/**
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include "../TEX_util.h"
+
+static bNodeSocketType inputs[]= {
+ { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { SOCK_VECTOR, 1, "Scale", 1.0f, 1.0f, 1.0f, 0.0f, -10.0f, 10.0f },
+ { -1, 0, "" }
+};
+
+static bNodeSocketType outputs[]= {
+ { SOCK_RGBA, 0, "Color", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
+ { -1, 0, "" }
+};
+
+static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ float scale[3], new_coord[3];
+
+ tex_input_vec(scale, in[1], coord, thread);
+
+ new_coord[0] = coord[0] * scale[0];
+ new_coord[1] = coord[1] * scale[1];
+ new_coord[2] = coord[2] * scale[2];
+
+ tex_input_rgba(out, in[0], new_coord, thread);
+}
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &colorfn);
+}
+
+bNodeType tex_node_scale = {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_SCALE,
+ /* name */ "Scale",
+ /* width+range */ 90, 80, 100,
+ /* class+opts */ NODE_CLASS_DISTORT, NODE_OPTIONS,
+ /* input sock */ inputs,
+ /* output sock */ outputs,
+ /* storage */ "",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+};
+
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_translate.c b/source/blender/nodes/intern/TEX_nodes/TEX_translate.c
index bd7e61d0ff4..0e903301789 100644
--- a/source/blender/nodes/intern/TEX_nodes/TEX_translate.c
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_translate.c
@@ -55,8 +55,6 @@ static void colorfn(float *out, float *coord, bNode *node, bNodeStack **in, shor
static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
{
tex_output(node, in, out[0], &colorfn);
-
- tex_do_preview(node, out[0], data);
}
bNodeType tex_node_translate = {
diff --git a/source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c b/source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c
new file mode 100644
index 00000000000..f63f5682030
--- /dev/null
+++ b/source/blender/nodes/intern/TEX_nodes/TEX_valToNor.c
@@ -0,0 +1,92 @@
+/**
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Jucas.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../TEX_util.h"
+
+static bNodeSocketType inputs[]= {
+ { SOCK_VALUE, 1, "Val", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
+ { SOCK_VALUE, 1, "Nabla", 0.025f, 0.0f, 0.0f, 0.0f, 0.001f, 0.1f },
+ { -1, 0, "" }
+};
+
+static bNodeSocketType outputs[]= {
+ { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
+ { -1, 0, "" }
+};
+
+static void normalfn(float *out, float *coord, bNode *node, bNodeStack **in, short thread)
+{
+ float new_coord[3];
+
+ float nabla = tex_input_value(in[1], coord, thread);
+ float val;
+ float nor[2];
+
+ val = tex_input_value(in[0], coord, thread);
+
+ new_coord[0] = coord[0] + nabla;
+ new_coord[1] = coord[1];
+ new_coord[2] = coord[2];
+ nor[0] = tex_input_value(in[0], new_coord, thread);
+
+ new_coord[0] = coord[0];
+ new_coord[1] = coord[1] + nabla;
+ nor[1] = tex_input_value(in[0], new_coord, thread);
+
+ new_coord[1] = coord[1];
+ new_coord[2] = coord[2] + nabla;
+ nor[2] = tex_input_value(in[0], new_coord, thread);
+
+ out[0] = val-nor[0];
+ out[1] = val-nor[1];
+ out[2] = val-nor[2];
+}
+static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
+{
+ tex_output(node, in, out[0], &normalfn);
+
+ tex_do_preview(node, out[0], data);
+}
+
+bNodeType tex_node_valtonor = {
+ /* *next,*prev */ NULL, NULL,
+ /* type code */ TEX_NODE_VALTONOR,
+ /* name */ "Value to Normal",
+ /* width+range */ 90, 80, 100,
+ /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS,
+ /* input sock */ inputs,
+ /* output sock */ outputs,
+ /* storage */ "",
+ /* execfunc */ exec,
+ /* butfunc */ NULL,
+ /* initfunc */ NULL,
+ /* freestoragefunc */ NULL,
+ /* copystoragefunc */ NULL,
+ /* id */ NULL
+};
+
diff --git a/source/blender/quicktime/apple/quicktime_import.c b/source/blender/quicktime/apple/quicktime_import.c
index 5a3c76b9d6f..1f3071f114c 100644
--- a/source/blender/quicktime/apple/quicktime_import.c
+++ b/source/blender/quicktime/apple/quicktime_import.c
@@ -159,6 +159,7 @@ int anim_is_quicktime (char *name)
BLI_testextensie(name, ".avi") || // wouldnt be appropriate ;)
BLI_testextensie(name, ".tga") ||
BLI_testextensie(name, ".png") ||
+ BLI_testextensie(name, ".bmp") ||
BLI_testextensie(name, ".jpg") ||
BLI_testextensie(name, ".wav") ||
BLI_testextensie(name, ".zip") ||
diff --git a/source/blender/yafray/intern/export_ri.cpp b/source/blender/yafray/intern/export_ri.cpp
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/source/blender/yafray/intern/export_ri.cpp
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 55e04783ab7..170d49fc1d8 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -210,7 +210,6 @@ IF(UNIX)
bf_editors
bf_decimation
blender_BSP
- bf_soundsystem
bf_ghost
bf_string
blender_render
@@ -271,10 +270,12 @@ IF(UNIX)
bf_quicktime
extern_binreloc
extern_glew
+ extern_libopenjpeg
bf_videotex
bf_rna
bf_dna
bf_blenfont
+ bf_soundsystem
)
FOREACH(SORTLIB ${BLENDER_SORTED_LIBS})
diff --git a/source/creator/Makefile b/source/creator/Makefile
index ea301ad80a9..fe281ad8d0e 100644
--- a/source/creator/Makefile
+++ b/source/creator/Makefile
@@ -59,6 +59,9 @@ CPPFLAGS += -I$(NAN_GLEW)/include
ifeq ($(WITH_QUICKTIME), true)
CPPFLAGS += -I$(NAN_QUICKTIME)/include -DWITH_QUICKTIME
endif
+ifeq ($(WITH_OPENJPEG), true)
+ CPPFLAGS += -DWITH_OPENJPEG
+endif
ifeq ($(WITH_BINRELOC), true)
CPPFLAGS += -I$(NANBLENDERHOME)/extern/binreloc/include -DWITH_BINRELOC
diff --git a/source/creator/creator.c b/source/creator/creator.c
index ad50e425415..69f80570334 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -751,7 +751,7 @@ int main(int argc, char **argv)
else if (!strcmp(argv[a],"CINEON")) scene->r.imtype = R_CINEON;
else if (!strcmp(argv[a],"DPX")) scene->r.imtype = R_DPX;
#if WITH_OPENJPEG
- else if (!strcmp(argv[a],"JP2")) G.scene->r.imtype = R_JP2;
+ else if (!strcmp(argv[a],"JP2")) scene->r.imtype = R_JP2;
#endif
else printf("\nError: Format from '-F' not known or not compiled in this release.\n");
}
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 8d443b9b386..90d5a1860aa 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -576,10 +576,12 @@ extern "C" void StartKetsjiShellSimulation(struct ScrArea *area,
// get some preferences
SYS_SystemHandle syshandle = SYS_GetSystem();
+ /*
bool properties = (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0);
bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0);
bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);
bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
+ */
bool game2ipo = true;//(SYS_GetCommandLineInt(syshandle, "game2ipo", 0) != 0);
bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0);
bool usemat = false;
diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt
index 2300323a55e..e090a4b9c56 100644
--- a/source/gameengine/BlenderRoutines/CMakeLists.txt
+++ b/source/gameengine/BlenderRoutines/CMakeLists.txt
@@ -40,5 +40,9 @@ SET(INC
${PYTHON_INC}
)
+IF(WITH_FFMPEG)
+ ADD_DEFINITIONS(-DWITH_FFMPEG)
+ENDIF(WITH_FFMPEG)
+
BLENDERLIB(bf_blroutines "${SRC}" "${INC}")
#env.BlenderLib ( 'bf_bloutines', sources, Split(incs), [], libtype=['game', 'game2', 'player'], priority=[0, 0, 55] , compileflags=cxxflags)
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
index 1797d6c1a0f..42ad7769cbd 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
@@ -80,7 +80,7 @@ void KX_BlenderRenderTools::EndFrame(RAS_IRasterizer* rasty)
* has a maximum of 8 lights (simultaneous), so 20 * 8 lights are possible in
* a scene. */
-void KX_BlenderRenderTools::ProcessLighting(int layer, const MT_Transform& viewmat)
+void KX_BlenderRenderTools::ProcessLighting(RAS_IRasterizer *rasty, int layer, const MT_Transform& viewmat)
{
if(m_lastlightlayer == layer)
return;
@@ -101,12 +101,12 @@ void KX_BlenderRenderTools::ProcessLighting(int layer, const MT_Transform& viewm
}
if(enable)
- EnableOpenGLLights();
+ EnableOpenGLLights(rasty);
else
DisableOpenGLLights();
}
-void KX_BlenderRenderTools::EnableOpenGLLights()
+void KX_BlenderRenderTools::EnableOpenGLLights(RAS_IRasterizer *rasty)
{
if(m_lastlighting == true)
return;
@@ -115,7 +115,8 @@ void KX_BlenderRenderTools::EnableOpenGLLights()
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, true);
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+ glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (rasty->GetCameraOrtho())? GL_FALSE: GL_TRUE);
if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2)
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
index a7618462c9b..ebf7562503f 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
@@ -60,9 +60,9 @@ public:
void EndFrame(RAS_IRasterizer* rasty);
void BeginFrame(RAS_IRasterizer* rasty);
- void EnableOpenGLLights();
+ void EnableOpenGLLights(RAS_IRasterizer *rasty);
void DisableOpenGLLights();
- void ProcessLighting(int layer, const MT_Transform& viewmat);
+ void ProcessLighting(RAS_IRasterizer *rasty, int layer, const MT_Transform& viewmat);
void RenderText2D(RAS_TEXT_RENDER_MODE mode,
const char* text,
diff --git a/source/gameengine/BlenderRoutines/Makefile b/source/gameengine/BlenderRoutines/Makefile
index b1be56ac47f..03a7a247727 100644
--- a/source/gameengine/BlenderRoutines/Makefile
+++ b/source/gameengine/BlenderRoutines/Makefile
@@ -77,3 +77,6 @@ endif
CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+ifeq ($(WITH_FFMPEG), true)
+ CPPFLAGS += -DWITH_FFMPEG
+endif
diff --git a/source/gameengine/BlenderRoutines/SConscript b/source/gameengine/BlenderRoutines/SConscript
index f7a3971e288..020402e9bcd 100644
--- a/source/gameengine/BlenderRoutines/SConscript
+++ b/source/gameengine/BlenderRoutines/SConscript
@@ -2,6 +2,7 @@
Import ('env')
sources = env.Glob('*.cpp')
+defs = []
incs = '. #source/kernel/gen_system #intern/string #intern/guardedalloc'
incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer #intern/bmfont'
@@ -12,19 +13,27 @@ incs += ' #source/blender/blenkernel #source/blender #source/blender/editors/inc
incs += ' #source/blender/makesdna #source/gameengine/Rasterizer #source/gameengine/GameLogic'
incs += ' #source/gameengine/Expressions #source/gameengine/Network'
incs += ' #source/gameengine/SceneGraph #source/gameengine/Physics/common'
-incs += ' #source/gameengine/Physics/Bullet #source/gameengine/Physics/Sumo'
-incs += ' #source/gameengine/Physics/Sumo/Fuzzics/include #source/gameengine/Network/LoopBackNetwork'
+incs += ' #source/gameengine/Physics/Bullet'
+incs += ' #source/gameengine/Network/LoopBackNetwork'
incs += ' #intern/SoundSystem #source/blender/misc #source/blender/blenloader'
incs += ' #extern/glew/include #source/blender/gpu'
incs += ' #source/blender/windowmanager'
+if env['WITH_BF_SOLID']:
+ incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/Fuzzics/include'
+ incs += ' ' + env['BF_SOLID_INC']
+ defs.append('USE_SUMO_SOLID')
+
+if env['WITH_BF_FFMPEG']:
+ defs.append('WITH_FFMPEG')
+
incs += ' ' + env['BF_PYTHON_INC']
-incs += ' ' + env['BF_SOLID_INC']
incs += ' ' + env['BF_BULLET_INC']
incs += ' ' + env['BF_OPENGL_INC']
cxxflags = []
if env['OURPLATFORM']=='win32-vc':
cxxflags.append ('/GR')
+ cxxflags.append ('/O2')
-env.BlenderLib ( 'bf_bloutines', sources, Split(incs), [], libtype=['core', 'player'], priority=[300, 45] , compileflags=cxxflags)
+env.BlenderLib ( 'bf_bloutines', sources, Split(incs), defs, libtype=['core', 'player'], priority=[300, 45] , cxx_compileflags=cxxflags)
diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp
index 536faa11b03..ce555fc1aeb 100644
--- a/source/gameengine/Converter/BL_ActionActuator.cpp
+++ b/source/gameengine/Converter/BL_ActionActuator.cpp
@@ -391,7 +391,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
/* Find percentages */
newweight = (m_blendframe/(float)m_blendin);
- blend_poses(m_pose, m_blendpose, 1.0 - newweight, ACTSTRIPMODE_BLEND);
+ // XXX blend_poses(m_pose, m_blendpose, 1.0 - newweight, ACTSTRIPMODE_BLEND);
/* Increment current blending percentage */
m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate();
@@ -1035,8 +1035,8 @@ PyAttributeDef BL_ActionActuator::Attributes[] = {
{ NULL } //Sentinel
};
-PyObject* BL_ActionActuator::_getattr(const STR_String& attr) {
- if (attr == "action")
+PyObject* BL_ActionActuator::_getattr(const char *attr) {
+ if (!strcmp(attr, "action"))
return PyString_FromString(m_action->id.name+2);
PyObject* object = _getattr_self(Attributes, this, attr);
if (object != NULL)
@@ -1044,8 +1044,8 @@ PyObject* BL_ActionActuator::_getattr(const STR_String& attr) {
_getattr_up(SCA_IActuator);
}
-int BL_ActionActuator::_setattr(const STR_String& attr, PyObject* value) {
- if (attr == "action")
+int BL_ActionActuator::_setattr(const char *attr, PyObject* value) {
+ if (!strcmp(attr, "action"))
{
if (!PyString_Check(value))
{
diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h
index 6e291106553..6161048afb8 100644
--- a/source/gameengine/Converter/BL_ActionActuator.h
+++ b/source/gameengine/Converter/BL_ActionActuator.h
@@ -110,8 +110,8 @@ public:
KX_PYMETHOD_DOC(BL_ActionActuator,setChannel);
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject* value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject* value);
/* attribute check */
static int CheckFrame(void *self, const PyAttributeDef*)
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 45461205fbb..da74fa49cba 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -361,7 +361,7 @@ BL_Material* ConvertMaterial(
facetex = true;
if(validface && mat->mtex[0]) {
MTex *tmp = mat->mtex[0];
- if(!tmp->tex || tmp->tex && !tmp->tex->ima )
+ if(!tmp->tex || (tmp->tex && !tmp->tex->ima))
facetex = true;
}
numchan = numchan>MAXTEX?MAXTEX:numchan;
@@ -593,7 +593,7 @@ BL_Material* ConvertMaterial(
MT_Point2 uv2[4];
const char *uvName = "", *uv2Name = "";
- uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f);
+
uv2[0]= uv2[1]= uv2[2]= uv2[3]= MT_Point2(0.0f, 0.0f);
if( validface ) {
@@ -607,12 +607,12 @@ BL_Material* ConvertMaterial(
material->tile = tface->tile;
material->mode = tface->mode;
- uv[0] = MT_Point2(tface->uv[0]);
- uv[1] = MT_Point2(tface->uv[1]);
- uv[2] = MT_Point2(tface->uv[2]);
+ uv[0].setValue(tface->uv[0]);
+ uv[1].setValue(tface->uv[1]);
+ uv[2].setValue(tface->uv[2]);
if (mface->v4)
- uv[3] = MT_Point2(tface->uv[3]);
+ uv[3].setValue(tface->uv[3]);
uvName = tfaceName;
}
@@ -622,6 +622,8 @@ BL_Material* ConvertMaterial(
material->mode = default_face_mode;
material->transp = TF_SOLID;
material->tile = 0;
+
+ uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f);
}
// with ztransp enabled, enforce alpha blending mode
@@ -665,14 +667,14 @@ BL_Material* ConvertMaterial(
{
MT_Point2 uvSet[4];
- uvSet[0] = MT_Point2(layer.face->uv[0]);
- uvSet[1] = MT_Point2(layer.face->uv[1]);
- uvSet[2] = MT_Point2(layer.face->uv[2]);
+ uvSet[0].setValue(layer.face->uv[0]);
+ uvSet[1].setValue(layer.face->uv[1]);
+ uvSet[2].setValue(layer.face->uv[2]);
if (mface->v4)
- uvSet[3] = MT_Point2(layer.face->uv[3]);
+ uvSet[3].setValue(layer.face->uv[3]);
else
- uvSet[3] = MT_Point2(0.0f, 0.0f);
+ uvSet[3].setValue(0.0f, 0.0f);
if (isFirstSet)
{
@@ -790,10 +792,10 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
MT_Vector4 tan0(0,0,0,0), tan1(0,0,0,0), tan2(0,0,0,0), tan3(0,0,0,0);
/* get coordinates, normals and tangents */
- pt0 = MT_Point3(mvert[mface->v1].co);
- pt1 = MT_Point3(mvert[mface->v2].co);
- pt2 = MT_Point3(mvert[mface->v3].co);
- pt3 = (mface->v4)? MT_Point3(mvert[mface->v4].co): MT_Point3(0.0, 0.0, 0.0);
+ pt0.setValue(mvert[mface->v1].co);
+ pt1.setValue(mvert[mface->v2].co);
+ pt2.setValue(mvert[mface->v3].co);
+ if (mface->v4) pt3.setValue(mvert[mface->v4].co);
if(mface->flag & ME_SMOOTH) {
float n0[3], n1[3], n2[3], n3[3];
@@ -894,12 +896,12 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
visible = !((mface->flag & ME_HIDE)||(tface->mode & TF_INVISIBLE));
- uv0 = MT_Point2(tface->uv[0]);
- uv1 = MT_Point2(tface->uv[1]);
- uv2 = MT_Point2(tface->uv[2]);
+ uv0.setValue(tface->uv[0]);
+ uv1.setValue(tface->uv[1]);
+ uv2.setValue(tface->uv[2]);
if (mface->v4)
- uv3 = MT_Point2(tface->uv[3]);
+ uv3.setValue(tface->uv[3]);
}
else {
/* no texfaces, set COLLSION true and everything else FALSE */
@@ -960,7 +962,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, RAS_IRenderTools*
polymat->m_diffuse = MT_Vector3(ma->r, ma->g, ma->b)*(ma->emit + ma->ref);
}
else {
- polymat->m_specular = MT_Vector3(0.0f,0.0f,0.0f);
+ polymat->m_specular.setValue(0.0f,0.0f,0.0f);
polymat->m_shininess = 35.0;
}
}
@@ -1313,6 +1315,12 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
CreateMaterialFromBlenderObject(blenderobject, kxscene);
KX_ObjectProperties objprop;
+ objprop.m_lockXaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_AXIS) !=0;
+ objprop.m_lockYaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_AXIS) !=0;
+ objprop.m_lockZaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_AXIS) !=0;
+ objprop.m_lockXRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_X_ROT_AXIS) !=0;
+ objprop.m_lockYRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Y_ROT_AXIS) !=0;
+ objprop.m_lockZRotaxis = (blenderobject->gameflag2 & OB_LOCK_RIGID_BODY_Z_ROT_AXIS) !=0;
objprop.m_isCompoundChild = isCompoundChild;
objprop.m_hasCompoundChildren = (blenderobject->gameflag & OB_CHILD) != 0;
@@ -1911,21 +1919,14 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
MT_Matrix3x3 angor;
if (converter->addInitFromFrame) blenderscene->r.cfra=blenderscene->r.sfra;
- MT_Point3 pos = MT_Point3(
+ MT_Point3 pos;
+ pos.setValue(
blenderobject->loc[0]+blenderobject->dloc[0],
blenderobject->loc[1]+blenderobject->dloc[1],
blenderobject->loc[2]+blenderobject->dloc[2]
);
- MT_Vector3 eulxyz = MT_Vector3(
- blenderobject->rot[0],
- blenderobject->rot[1],
- blenderobject->rot[2]
- );
- MT_Vector3 scale = MT_Vector3(
- blenderobject->size[0],
- blenderobject->size[1],
- blenderobject->size[2]
- );
+ MT_Vector3 eulxyz(blenderobject->rot);
+ MT_Vector3 scale(blenderobject->size);
if (converter->addInitFromFrame){//rcruiz
float eulxyzPrev[3];
blenderscene->r.cfra=blenderscene->r.sfra-1;
@@ -1997,18 +1998,18 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
MT_Vector3 x(ori.getColumn(0));
MT_Vector3 y(ori.getColumn(1));
MT_Vector3 z(ori.getColumn(2));
- MT_Vector3 scale(x.length(), y.length(), z.length());
- if (!MT_fuzzyZero(scale[0]))
- x /= scale[0];
- if (!MT_fuzzyZero(scale[1]))
- y /= scale[1];
- if (!MT_fuzzyZero(scale[2]))
- z /= scale[2];
+ MT_Vector3 parscale(x.length(), y.length(), z.length());
+ if (!MT_fuzzyZero(parscale[0]))
+ x /= parscale[0];
+ if (!MT_fuzzyZero(parscale[1]))
+ y /= parscale[1];
+ if (!MT_fuzzyZero(parscale[2]))
+ z /= parscale[2];
ori.setColumn(0, x);
ori.setColumn(1, y);
ori.setColumn(2, z);
parentinversenode->SetLocalOrientation(ori);
- parentinversenode->SetLocalScale(scale);
+ parentinversenode->SetLocalScale(parscale);
parentinversenode->AddChild(gameobj->GetSGNode());
}
@@ -2113,21 +2114,13 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
if (converter->addInitFromFrame)
blenderscene->r.cfra=blenderscene->r.sfra;
- MT_Point3 pos = MT_Point3(
+ MT_Point3 pos(
blenderobject->loc[0]+blenderobject->dloc[0],
blenderobject->loc[1]+blenderobject->dloc[1],
blenderobject->loc[2]+blenderobject->dloc[2]
);
- MT_Vector3 eulxyz = MT_Vector3(
- blenderobject->rot[0],
- blenderobject->rot[1],
- blenderobject->rot[2]
- );
- MT_Vector3 scale = MT_Vector3(
- blenderobject->size[0],
- blenderobject->size[1],
- blenderobject->size[2]
- );
+ MT_Vector3 eulxyz(blenderobject->rot);
+ MT_Vector3 scale(blenderobject->size);
if (converter->addInitFromFrame){//rcruiz
float eulxyzPrev[3];
blenderscene->r.cfra=blenderscene->r.sfra-1;
@@ -2194,18 +2187,18 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
MT_Vector3 x(ori.getColumn(0));
MT_Vector3 y(ori.getColumn(1));
MT_Vector3 z(ori.getColumn(2));
- MT_Vector3 scale(x.length(), y.length(), z.length());
- if (!MT_fuzzyZero(scale[0]))
- x /= scale[0];
- if (!MT_fuzzyZero(scale[1]))
- y /= scale[1];
- if (!MT_fuzzyZero(scale[2]))
- z /= scale[2];
+ MT_Vector3 localscale(x.length(), y.length(), z.length());
+ if (!MT_fuzzyZero(localscale[0]))
+ x /= localscale[0];
+ if (!MT_fuzzyZero(localscale[1]))
+ y /= localscale[1];
+ if (!MT_fuzzyZero(localscale[2]))
+ z /= localscale[2];
ori.setColumn(0, x);
ori.setColumn(1, y);
ori.setColumn(2, z);
parentinversenode->SetLocalOrientation(ori);
- parentinversenode->SetLocalScale(scale);
+ parentinversenode->SetLocalScale(localscale);
parentinversenode->AddChild(gameobj->GetSGNode());
}
diff --git a/source/gameengine/Converter/BL_MeshDeformer.cpp b/source/gameengine/Converter/BL_MeshDeformer.cpp
index fa3b8185fe2..80112346c72 100644
--- a/source/gameengine/Converter/BL_MeshDeformer.cpp
+++ b/source/gameengine/Converter/BL_MeshDeformer.cpp
@@ -51,7 +51,6 @@
bool BL_MeshDeformer::Apply(RAS_IPolyMaterial*)
{
size_t i;
- float *co;
// only apply once per frame if the mesh is actually modified
if(m_pMeshObject->MeshModified() &&
@@ -70,8 +69,7 @@ bool BL_MeshDeformer::Apply(RAS_IPolyMaterial*)
// For each vertex
for(i=it.startvertex; i<it.endvertex; i++) {
RAS_TexVert& v = it.vertex[i];
- co = m_bmesh->mvert[v.getOrigIndex()].co;
- v.SetXYZ(MT_Point3(co));
+ v.SetXYZ(m_bmesh->mvert[v.getOrigIndex()].co);
}
}
}
diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.cpp b/source/gameengine/Converter/BL_ShapeActionActuator.cpp
index df1aed38ceb..f4e3e7e0ae8 100644
--- a/source/gameengine/Converter/BL_ShapeActionActuator.cpp
+++ b/source/gameengine/Converter/BL_ShapeActionActuator.cpp
@@ -484,8 +484,8 @@ PyAttributeDef BL_ShapeActionActuator::Attributes[] = {
};
-PyObject* BL_ShapeActionActuator::_getattr(const STR_String& attr) {
- if (attr == "action")
+PyObject* BL_ShapeActionActuator::_getattr(const char *attr) {
+ if (!strcmp(attr, "action"))
return PyString_FromString(m_action->id.name+2);
PyObject* object = _getattr_self(Attributes, this, attr);
if (object != NULL)
@@ -493,8 +493,8 @@ PyObject* BL_ShapeActionActuator::_getattr(const STR_String& attr) {
_getattr_up(SCA_IActuator);
}
-int BL_ShapeActionActuator::_setattr(const STR_String& attr, PyObject* value) {
- if (attr == "action")
+int BL_ShapeActionActuator::_setattr(const char *attr, PyObject* value) {
+ if (!strcmp(attr, "action"))
{
if (!PyString_Check(value))
{
@@ -911,6 +911,6 @@ PyObject* BL_ShapeActionActuator::PySetType(PyObject* self,
printf("Invalid type for action actuator: %d\n", typeArg); /* error */
}
- Py_Return;
+ Py_RETURN_NONE;
}
diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.h b/source/gameengine/Converter/BL_ShapeActionActuator.h
index b521c0d98a6..7f2431bcfa5 100644
--- a/source/gameengine/Converter/BL_ShapeActionActuator.h
+++ b/source/gameengine/Converter/BL_ShapeActionActuator.h
@@ -103,8 +103,8 @@ public:
KX_PYMETHOD_DOC_NOARGS(BL_ShapeActionActuator,GetType);
KX_PYMETHOD_DOC(BL_ShapeActionActuator,SetType);
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject* value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject* value);
static int CheckBlendTime(void *self, const PyAttributeDef*)
{
@@ -169,8 +169,8 @@ protected:
short m_playtype;
short m_priority;
struct bAction *m_action;
- STR_String m_propname;
STR_String m_framepropname;
+ STR_String m_propname;
vector<float> m_blendshape;
};
diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
index 7b68dbda176..7daca6c32fe 100644
--- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
+++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
@@ -321,7 +321,7 @@ void KX_BlenderSceneConverter::ConvertScene(const STR_String& scenename,
SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
int visualizePhysics = SYS_GetCommandLineInt(syshandle,"show_physics",0);
if (visualizePhysics)
- ccdPhysEnv->setDebugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb|btIDebugDraw::DBG_DrawContactPoints|btIDebugDraw::DBG_DrawText);
+ ccdPhysEnv->setDebugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb|btIDebugDraw::DBG_DrawContactPoints|btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_DrawConstraintLimits|btIDebugDraw::DBG_DrawConstraints);
//todo: get a button in blender ?
//disable / enable debug drawing (contact points, aabb's etc)
@@ -663,7 +663,7 @@ extern "C"
Ipo *add_ipo( char *name, int idcode );
//XXX char *getIpoCurveName( IpoCurve * icu );
//XXX struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, char *, int);
- void testhandles_ipocurve(struct IpoCurve *icu);
+ //XXX void testhandles_ipocurve(struct IpoCurve *icu);
void insert_vert_icu(struct IpoCurve *, float, float, short);
void Mat3ToEul(float tmat[][3], float *eul);
}
@@ -751,7 +751,7 @@ void KX_BlenderSceneConverter::ResetPhysicsObjectsAnimationIpo(bool clearIpo)
}
}
} else
- { ipo = add_ipo(blenderObject->id.name+2, ID_OB);
+ { ipo = NULL; // XXX add_ipo(blenderObject->id.name+2, ID_OB);
blenderObject->ipo = ipo;
}
@@ -907,7 +907,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
float curVal = position.x();
//XXX insert_vert_icu(icu1, frameNumber, curVal, 0);
#ifdef TEST_HANDLES_GAME2IPO
- testhandles_ipocurve(icu1);
+ //XXX testhandles_ipocurve(icu1);
#endif
}
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY");
@@ -917,7 +917,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
//XXX insert_vert_icu(icu1, frameNumber, curVal, 0);
#ifdef TEST_HANDLES_GAME2IPO
- testhandles_ipocurve(icu1);
+ //XXX testhandles_ipocurve(icu1);
#endif
}
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ");
@@ -926,7 +926,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
float curVal = position.z();
//XXX insert_vert_icu(icu1, frameNumber, curVal, 0);
#ifdef TEST_HANDLES_GAME2IPO
- testhandles_ipocurve(icu1);
+ //XXX testhandles_ipocurve(icu1);
#endif
}
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX");
@@ -936,7 +936,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
//XXX insert_vert_icu(icu1, frameNumber, curVal, 0);
#ifdef TEST_HANDLES_GAME2IPO
- testhandles_ipocurve(icu1);
+ //XXX testhandles_ipocurve(icu1);
#endif
}
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY");
@@ -946,7 +946,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
//XXX insert_vert_icu(icu1, frameNumber, curVal, 0);
#ifdef TEST_HANDLES_GAME2IPO
- testhandles_ipocurve(icu1);
+ //XXX testhandles_ipocurve(icu1);
#endif
}
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ");
@@ -956,7 +956,7 @@ void KX_BlenderSceneConverter::WritePhysicsObjectToAnimationIpo(int frameNumber)
//XXX insert_vert_icu(icu1, frameNumber, curVal, 0);
#ifdef TEST_HANDLES_GAME2IPO
- testhandles_ipocurve(icu1);
+ //XXX testhandles_ipocurve(icu1);
#endif
}
@@ -1060,32 +1060,32 @@ void KX_BlenderSceneConverter::TestHandlesPhysicsObjectToAnimationIpo()
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocX");
if (icu1)
{
- testhandles_ipocurve(icu1);
+ //XXX testhandles_ipocurve(icu1);
}
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocY");
if (icu1)
{
- testhandles_ipocurve(icu1);
+ //XXX testhandles_ipocurve(icu1);
}
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"LocZ");
if (icu1)
{
- testhandles_ipocurve(icu1);
+ //XXX testhandles_ipocurve(icu1);
}
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotX");
if (icu1)
{
- testhandles_ipocurve(icu1);
+ //XXX testhandles_ipocurve(icu1);
}
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotY");
if (icu1)
{
- testhandles_ipocurve(icu1);
+ //XXX testhandles_ipocurve(icu1);
}
icu1 = findIpoCurve((IpoCurve *)ipo->curve.first,"RotZ");
if (icu1)
{
- testhandles_ipocurve(icu1);
+ //XXX testhandles_ipocurve(icu1);
}
}
diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp
index da490b4ee85..fb100b0a68b 100644
--- a/source/gameengine/Converter/KX_ConvertControllers.cpp
+++ b/source/gameengine/Converter/KX_ConvertControllers.cpp
@@ -200,6 +200,13 @@ void BL_ConvertControllers(
gameobj->AddController(gamecontroller);
converter->RegisterGameController(gamecontroller, bcontr);
+
+ if (bcontr->type==CONT_PYTHON) {
+ /* not strictly needed but gives syntax errors early on and
+ * gives more pradictable performance for larger scripts */
+ (static_cast<SCA_PythonController*>(gamecontroller))->Compile();
+ }
+
//done with gamecontroller
gamecontroller->Release();
}
diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp
index b7b47b3b39f..c91197b72a6 100644
--- a/source/gameengine/Converter/KX_ConvertSensors.cpp
+++ b/source/gameengine/Converter/KX_ConvertSensors.cpp
@@ -317,12 +317,12 @@ void BL_ConvertSensors(struct Object* blenderobject,
{
// collision sensor can sense both materials and properties.
- bool bFindMaterial = false;
+ bool bFindMaterial = false, bTouchPulse = false;
bCollisionSensor* blendertouchsensor = (bCollisionSensor*)sens->data;
- bFindMaterial = (blendertouchsensor->mode
- & SENS_COLLISION_MATERIAL);
+ bFindMaterial = (blendertouchsensor->mode & SENS_COLLISION_MATERIAL);
+ bTouchPulse = (blendertouchsensor->mode & SENS_COLLISION_PULSE);
STR_String touchPropOrMatName = ( bFindMaterial ?
@@ -335,6 +335,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
gamesensor = new KX_TouchSensor(eventmgr,
gameobj,
bFindMaterial,
+ bTouchPulse,
touchPropOrMatName);
}
@@ -360,6 +361,7 @@ void BL_ConvertSensors(struct Object* blenderobject,
gamesensor = new KX_TouchSensor(eventmgr,
gameobj,
bFindMaterial,
+ false,
touchpropertyname);
}
}
diff --git a/source/gameengine/Converter/KX_IpoConvert.cpp b/source/gameengine/Converter/KX_IpoConvert.cpp
index ce004fa0504..f19390db8a9 100644
--- a/source/gameengine/Converter/KX_IpoConvert.cpp
+++ b/source/gameengine/Converter/KX_IpoConvert.cpp
@@ -311,67 +311,67 @@ void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_Blend
}
{
- KX_ObColorIpoSGController* ipocontr=NULL;
+ KX_ObColorIpoSGController* ipocontr_obcol=NULL;
ipo = ipoList->GetScalarInterpolator(OB_COL_R);
if (ipo)
{
- if (!ipocontr)
+ if (!ipocontr_obcol)
{
- ipocontr = new KX_ObColorIpoSGController();
- gameobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(gameobj->GetSGNode());
+ ipocontr_obcol = new KX_ObColorIpoSGController();
+ gameobj->GetSGNode()->AddSGController(ipocontr_obcol);
+ ipocontr_obcol->SetObject(gameobj->GetSGNode());
}
KX_IInterpolator *interpolator =
new KX_ScalarInterpolator(
- &ipocontr->m_rgba[0],
+ &ipocontr_obcol->m_rgba[0],
ipo);
- ipocontr->AddInterpolator(interpolator);
+ ipocontr_obcol->AddInterpolator(interpolator);
}
ipo = ipoList->GetScalarInterpolator(OB_COL_G);
if (ipo)
{
- if (!ipocontr)
+ if (!ipocontr_obcol)
{
- ipocontr = new KX_ObColorIpoSGController();
- gameobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(gameobj->GetSGNode());
+ ipocontr_obcol = new KX_ObColorIpoSGController();
+ gameobj->GetSGNode()->AddSGController(ipocontr_obcol);
+ ipocontr_obcol->SetObject(gameobj->GetSGNode());
}
KX_IInterpolator *interpolator =
new KX_ScalarInterpolator(
- &ipocontr->m_rgba[1],
+ &ipocontr_obcol->m_rgba[1],
ipo);
- ipocontr->AddInterpolator(interpolator);
+ ipocontr_obcol->AddInterpolator(interpolator);
}
ipo = ipoList->GetScalarInterpolator(OB_COL_B);
if (ipo)
{
- if (!ipocontr)
+ if (!ipocontr_obcol)
{
- ipocontr = new KX_ObColorIpoSGController();
- gameobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(gameobj->GetSGNode());
+ ipocontr_obcol = new KX_ObColorIpoSGController();
+ gameobj->GetSGNode()->AddSGController(ipocontr_obcol);
+ ipocontr_obcol->SetObject(gameobj->GetSGNode());
}
KX_IInterpolator *interpolator =
new KX_ScalarInterpolator(
- &ipocontr->m_rgba[2],
+ &ipocontr_obcol->m_rgba[2],
ipo);
- ipocontr->AddInterpolator(interpolator);
+ ipocontr_obcol->AddInterpolator(interpolator);
}
ipo = ipoList->GetScalarInterpolator(OB_COL_A);
if (ipo)
{
- if (!ipocontr)
+ if (!ipocontr_obcol)
{
- ipocontr = new KX_ObColorIpoSGController();
- gameobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(gameobj->GetSGNode());
+ ipocontr_obcol = new KX_ObColorIpoSGController();
+ gameobj->GetSGNode()->AddSGController(ipocontr_obcol);
+ ipocontr_obcol->SetObject(gameobj->GetSGNode());
}
KX_IInterpolator *interpolator =
new KX_ScalarInterpolator(
- &ipocontr->m_rgba[3],
+ &ipocontr_obcol->m_rgba[3],
ipo);
- ipocontr->AddInterpolator(interpolator);
+ ipocontr_obcol->AddInterpolator(interpolator);
}
}
diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript
index 5c2ab49a04c..98b7c71bad2 100644
--- a/source/gameengine/Converter/SConscript
+++ b/source/gameengine/Converter/SConscript
@@ -2,6 +2,7 @@
Import ('env')
sources = env.Glob('*.cpp')
+defs = []
incs = '. #source/kernel/gen_system #intern/string #intern/guardedalloc'
incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer #intern/bmfont'
@@ -14,13 +15,17 @@ incs += ' #source/blender/editors/include #source/blender/makesdna #source/gamee
incs += ' #source/gameengine/Rasterizer/RAS_OpenGLRasterizer #source/gameengine/GameLogic'
incs += ' #source/gameengine/Expressions #source/gameengine/Network #source/gameengine/SceneGraph'
incs += ' #source/gameengine/Physics/common #source/gameengine/Physics/Bullet #source/gameengine/Physics/BlOde'
-incs += ' #source/gameengine/Physics/Dummy #source/gameengine/Physics/Sumo'
-incs += ' #source/gameengine/Physics/Sumo/Fuzzics/include #source/gameengine/Network/LoopBackNetwork'
+incs += ' #source/gameengine/Physics/Dummy'
+incs += ' #source/gameengine/Network/LoopBackNetwork'
incs += ' #source/blender/misc #source/blender/blenloader #source/blender/gpu'
incs += ' #source/blender/windowmanager'
+if env['WITH_BF_SOLID']:
+ incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/Fuzzics/include'
+ incs += ' ' + env['BF_SOLID_INC']
+ defs.append('USE_SUMO_SOLID')
+
incs += ' ' + env['BF_PYTHON_INC']
-incs += ' ' + env['BF_SOLID_INC']
incs += ' ' + env['BF_BULLET_INC']
-env.BlenderLib ( 'bf_converter', sources, Split(incs), [], libtype=['core','player'], priority=[305,50] )
+env.BlenderLib ( 'bf_converter', sources, Split(incs), defs, libtype=['core','player'], priority=[305,50] )
diff --git a/source/gameengine/Expressions/FloatValue.cpp b/source/gameengine/Expressions/FloatValue.cpp
index 93f102d04a6..460eaa73f35 100644
--- a/source/gameengine/Expressions/FloatValue.cpp
+++ b/source/gameengine/Expressions/FloatValue.cpp
@@ -127,6 +127,9 @@ ret: a new object containing the result of applying operator op to val and
{
switch (op)
{
+ case VALUE_MOD_OPERATOR:
+ ret = new CFloatValue(fmod(((CIntValue *) val)->GetInt(), m_float));
+ break;
case VALUE_ADD_OPERATOR:
ret = new CFloatValue(((CIntValue *) val)->GetInt() + m_float);
break;
@@ -171,6 +174,9 @@ ret: a new object containing the result of applying operator op to val and
{
switch (op)
{
+ case VALUE_MOD_OPERATOR:
+ ret = new CFloatValue(fmod(((CFloatValue *) val)->GetFloat(), m_float));
+ break;
case VALUE_ADD_OPERATOR:
ret = new CFloatValue(((CFloatValue *) val)->GetFloat() + m_float);
break;
diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp
index 32a9de32e21..94663c4a365 100644
--- a/source/gameengine/Expressions/InputParser.cpp
+++ b/source/gameengine/Expressions/InputParser.cpp
@@ -38,6 +38,9 @@
// cool things like (IF(LOD==1,CCurvedValue,IF(LOD==2,CCurvedValue2)) etc...
#include "IfExpr.h"
+#if defined(WIN32) || defined(WIN64)
+#define strcasecmp _stricmp
+#endif /* Def WIN32 or Def WIN64 */
#define NUM_PRIORITY 6
//////////////////////////////////////////////////////////////////////
@@ -172,6 +175,9 @@ void CParser::NextSym()
case ',':
sym = commasym; NextCh();
break;
+ case '%' :
+ sym = opsym; opkind = OPmodulus; NextCh();
+ break;
case '+' :
sym = opsym; opkind = OPplus; NextCh();
break;
@@ -271,33 +277,30 @@ void CParser::NextSym()
} else if (((ch >= 'a') && (ch <= 'z'))
|| ((ch >= 'A') && (ch <= 'Z')))
{ // reserved word?
- int start;
- STR_String funstr;
+
start = chcount;
CharRep();
GrabString(start);
- funstr = const_as_string;
- funstr.Upper();
- if (funstr == STR_String("SUM")) {
+ if (!strcasecmp(const_as_string, "SUM")) {
sym = sumsym;
}
- else if (funstr == STR_String("NOT")) {
+ else if (!strcasecmp(const_as_string, "NOT")) {
sym = opsym;
opkind = OPnot;
}
- else if (funstr == STR_String("AND")) {
+ else if (!strcasecmp(const_as_string, "AND")) {
sym = opsym; opkind = OPand;
}
- else if (funstr == STR_String("OR")) {
+ else if (!strcasecmp(const_as_string, "OR")) {
sym = opsym; opkind = OPor;
}
- else if (funstr == STR_String("IF")) {
+ else if (!strcasecmp(const_as_string, "IF"))
sym = ifsym;
- } else if (funstr == STR_String("WHOMADE")) {
+ else if (!strcasecmp(const_as_string, "WHOMADE"))
sym = whocodedsym;
- } else if (funstr == STR_String("FALSE")) {
+ else if (!strcasecmp(const_as_string, "FALSE")) {
sym = constsym; constkind = booltype; boolvalue = false;
- } else if (funstr == STR_String("TRUE")) {
+ } else if (!strcasecmp(const_as_string, "TRUE")) {
sym = constsym; constkind = booltype; boolvalue = true;
} else {
sym = idsym;
@@ -370,6 +373,7 @@ int CParser::Priority(int optorkind) {
case OPunequal: return 3;
case OPplus:
case OPminus: return 4;
+ case OPmodulus:
case OPtimes:
case OPdivide: return 5;
}
@@ -390,6 +394,7 @@ CExpression *CParser::Ex(int i) {
NextSym();
e2 = Ex(i + 1);
switch(opkind2) {
+ case OPmodulus: e1 = new COperator2Expr(VALUE_MOD_OPERATOR,e1, e2); break;
case OPplus: e1 = new COperator2Expr(VALUE_ADD_OPERATOR,e1, e2); break;
case OPminus: e1 = new COperator2Expr(VALUE_SUB_OPERATOR,e1, e2); break;
case OPtimes: e1 = new COperator2Expr(VALUE_MUL_OPERATOR,e1, e2); break;
diff --git a/source/gameengine/Expressions/InputParser.h b/source/gameengine/Expressions/InputParser.h
index 4caa47cbb0c..f51c473ba18 100644
--- a/source/gameengine/Expressions/InputParser.h
+++ b/source/gameengine/Expressions/InputParser.h
@@ -49,6 +49,7 @@ private:
}; // all kinds of symbols
enum optype {
+ OPmodulus,
OPplus,
OPminus,
OPtimes,
diff --git a/source/gameengine/Expressions/IntValue.cpp b/source/gameengine/Expressions/IntValue.cpp
index fbf4f4f59e0..fb586cb4979 100644
--- a/source/gameengine/Expressions/IntValue.cpp
+++ b/source/gameengine/Expressions/IntValue.cpp
@@ -125,6 +125,9 @@ this object
case VALUE_INT_TYPE:
{
switch (op) {
+ case VALUE_MOD_OPERATOR:
+ ret = new CIntValue (((CIntValue *) val)->GetInt() % m_int);
+ break;
case VALUE_ADD_OPERATOR:
ret = new CIntValue (((CIntValue *) val)->GetInt() + m_int);
break;
@@ -181,6 +184,9 @@ this object
case VALUE_FLOAT_TYPE:
{
switch (op) {
+ case VALUE_MOD_OPERATOR:
+ ret = new CFloatValue(fmod(((CFloatValue *) val)->GetFloat(), m_int));
+ break;
case VALUE_ADD_OPERATOR:
ret = new CFloatValue (((CFloatValue *) val)->GetFloat() + m_int);
break;
diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp
index 9ffdbb1223c..90a939af236 100644
--- a/source/gameengine/Expressions/ListValue.cpp
+++ b/source/gameengine/Expressions/ListValue.cpp
@@ -34,7 +34,12 @@ Py_ssize_t listvalue_bufferlen(PyObject* list)
PyObject* listvalue_buffer_item(PyObject* list,Py_ssize_t index)
{
- if (index >= 0 && index < ((CListValue*) list)->GetCount())
+ int count = ((CListValue*) list)->GetCount();
+
+ if (index < 0)
+ index = count+index;
+
+ if (index >= 0 && index < count)
{
PyObject* pyobj = ((CListValue*) list)->GetValue(index)->ConvertValueToPython();
if (pyobj)
@@ -64,8 +69,7 @@ PyObject* listvalue_mapping_subscript(PyObject* list,PyObject* pyindex)
}
PyObject *pyindex_str = PyObject_Repr(pyindex); /* new ref */
- STR_String index_str(PyString_AsString(pyindex_str));
- PyErr_Format(PyExc_KeyError, "'%s' not in list", index_str.Ptr());
+ PyErr_Format(PyExc_KeyError, "'%s' not in list", PyString_AsString(pyindex_str));
Py_DECREF(pyindex_str);
return NULL;
}
@@ -220,17 +224,19 @@ PyParentObject CListValue::Parents[] = {
PyMethodDef CListValue::Methods[] = {
- {"append", (PyCFunction)CListValue::sPyappend,METH_VARARGS},
- {"reverse", (PyCFunction)CListValue::sPyreverse,METH_VARARGS},
- {"index", (PyCFunction)CListValue::sPyindex,METH_VARARGS},
- {"count", (PyCFunction)CListValue::sPycount,METH_VARARGS},
+ {"append", (PyCFunction)CListValue::sPyappend,METH_O},
+ {"reverse", (PyCFunction)CListValue::sPyreverse,METH_NOARGS},
+ {"index", (PyCFunction)CListValue::sPyindex,METH_O},
+ {"count", (PyCFunction)CListValue::sPycount,METH_O},
{NULL,NULL} //Sentinel
};
+PyAttributeDef CListValue::Attributes[] = {
+ { NULL } //Sentinel
+};
-
-PyObject* CListValue::_getattr(const STR_String& attr) {
+PyObject* CListValue::_getattr(const char *attr) {
_getattr_up(CValue);
}
@@ -399,34 +405,17 @@ void CListValue::MergeList(CListValue *otherlist)
-PyObject* CListValue::Pyappend(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* CListValue::Pyappend(PyObject* self, PyObject* value)
{
-
- PyObject* pyobj = NULL;
- if (PyArg_ParseTuple(args,"O",&pyobj))
- {
- return listvalue_buffer_concat(self,pyobj);
- }
- else
- {
- return NULL;
- }
-
-
+ return listvalue_buffer_concat(self, value);
}
-PyObject* CListValue::Pyreverse(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* CListValue::Pyreverse(PyObject* self)
{
std::reverse(m_pValueArray.begin(),m_pValueArray.end());
-
- Py_Return;
-
+ Py_RETURN_NONE;
}
@@ -448,58 +437,56 @@ bool CListValue::CheckEqual(CValue* first,CValue* second)
-PyObject* CListValue::Pyindex(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* CListValue::Pyindex(PyObject* self, PyObject *value)
{
PyObject* result = NULL;
- PyObject* pyobj = NULL;
- if (PyArg_ParseTuple(args,"O",&pyobj))
+ CValue* checkobj = ConvertPythonToValue(value);
+ if (checkobj==NULL)
+ return NULL; /* ConvertPythonToValue sets the error */
+
+ int numelem = GetCount();
+ for (int i=0;i<numelem;i++)
{
-
- CValue* checkobj = ConvertPythonToValue(pyobj);
- int numelem = GetCount();
- for (int i=0;i<numelem;i++)
+ CValue* elem = GetValue(i);
+ if (CheckEqual(checkobj,elem))
{
- CValue* elem = GetValue(i);
- if (CheckEqual(checkobj,elem))
- {
- result = PyInt_FromLong(i);
- break;
- }
+ result = PyInt_FromLong(i);
+ break;
}
- checkobj->Release();
}
+ checkobj->Release();
+ if (result==NULL) {
+ PyErr_SetString(PyExc_ValueError, "ValueError: list.index(x): x not in CListValue");
+ }
return result;
}
-PyObject* CListValue::Pycount(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* CListValue::Pycount(PyObject* self, PyObject* value)
{
-
int numfound = 0;
- PyObject* pyobj = NULL;
- if (PyArg_ParseTuple(args,"O",&pyobj))
+ CValue* checkobj = ConvertPythonToValue(value);
+
+ if (checkobj==NULL) { /* in this case just return that there are no items in the list */
+ PyErr_Clear();
+ PyInt_FromLong(0);
+ }
+
+ int numelem = GetCount();
+ for (int i=0;i<numelem;i++)
{
- CValue* checkobj = ConvertPythonToValue(pyobj);
- int numelem = GetCount();
- for (int i=0;i<numelem;i++)
+ CValue* elem = GetValue(i);
+ if (CheckEqual(checkobj,elem))
{
- CValue* elem = GetValue(i);
- if (CheckEqual(checkobj,elem))
- {
- numfound ++;
- }
+ numfound ++;
}
- checkobj->Release();
}
+ checkobj->Release();
return PyInt_FromLong(numfound);
}
diff --git a/source/gameengine/Expressions/ListValue.h b/source/gameengine/Expressions/ListValue.h
index 431f8f558a9..104e3e63283 100644
--- a/source/gameengine/Expressions/ListValue.h
+++ b/source/gameengine/Expressions/ListValue.h
@@ -59,12 +59,12 @@ public:
bool CheckEqual(CValue* first,CValue* second);
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
- KX_PYMETHOD(CListValue,append);
- KX_PYMETHOD(CListValue,reverse);
- KX_PYMETHOD(CListValue,index);
- KX_PYMETHOD(CListValue,count);
+ KX_PYMETHOD_O(CListValue,append);
+ KX_PYMETHOD_NOARGS(CListValue,reverse);
+ KX_PYMETHOD_O(CListValue,index);
+ KX_PYMETHOD_O(CListValue,count);
private:
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp
index 8fd99c8d267..1bead0a7664 100644
--- a/source/gameengine/Expressions/PyObjectPlus.cpp
+++ b/source/gameengine/Expressions/PyObjectPlus.cpp
@@ -94,7 +94,7 @@ PyObjectPlus::PyObjectPlus(PyTypeObject *T) // constructor
* PyObjectPlus Methods -- Every class, even the abstract one should have a Methods
------------------------------*/
PyMethodDef PyObjectPlus::Methods[] = {
- {"isA", (PyCFunction) sPy_isA, METH_VARARGS},
+ {"isA", (PyCFunction) sPy_isA, METH_O},
{NULL, NULL} /* Sentinel */
};
@@ -106,24 +106,24 @@ PyParentObject PyObjectPlus::Parents[] = {&PyObjectPlus::Type, NULL};
/*------------------------------
* PyObjectPlus attributes -- attributes
------------------------------*/
-PyObject *PyObjectPlus::_getattr(const STR_String& attr)
+PyObject *PyObjectPlus::_getattr(const char *attr)
{
- if (attr == "__doc__" && GetType()->tp_doc)
+ if (!strcmp(attr, "__doc__") && GetType()->tp_doc)
return PyString_FromString(GetType()->tp_doc);
//if (streq(attr, "type"))
// return Py_BuildValue("s", (*(GetParents()))->tp_name);
- return Py_FindMethod(Methods, this, const_cast<char *>(attr.ReadPtr()));
+ return Py_FindMethod(Methods, this, attr);
}
-int PyObjectPlus::_delattr(const STR_String& attr)
+int PyObjectPlus::_delattr(const char *attr)
{
PyErr_SetString(PyExc_AttributeError, "attribute cant be deleted");
return 1;
}
-int PyObjectPlus::_setattr(const STR_String& attr, PyObject *value)
+int PyObjectPlus::_setattr(const char *attr, PyObject *value)
{
//return PyObject::_setattr(attr,value);
//cerr << "Unknown attribute" << endl;
@@ -131,12 +131,12 @@ int PyObjectPlus::_setattr(const STR_String& attr, PyObject *value)
return 1;
}
-PyObject *PyObjectPlus::_getattr_self(const PyAttributeDef attrlist[], void *self, const STR_String &attr)
+PyObject *PyObjectPlus::_getattr_self(const PyAttributeDef attrlist[], void *self, const char *attr)
{
const PyAttributeDef *attrdef;
for (attrdef=attrlist; attrdef->m_name != NULL; attrdef++)
{
- if (attr == attrdef->m_name)
+ if (!strcmp(attr, attrdef->m_name))
{
if (attrdef->m_type == KX_PYATTRIBUTE_TYPE_DUMMY)
{
@@ -147,7 +147,7 @@ PyObject *PyObjectPlus::_getattr_self(const PyAttributeDef attrlist[], void *sel
if (attrdef->m_length > 1)
{
PyObject* resultlist = PyList_New(attrdef->m_length);
- for (int i=0; i<attrdef->m_length; i++)
+ for (unsigned int i=0; i<attrdef->m_length; i++)
{
switch (attrdef->m_type) {
case KX_PYATTRIBUTE_TYPE_BOOL:
@@ -238,7 +238,7 @@ PyObject *PyObjectPlus::_getattr_self(const PyAttributeDef attrlist[], void *sel
return NULL;
}
-int PyObjectPlus::_setattr_self(const PyAttributeDef attrlist[], void *self, const STR_String &attr, PyObject *value)
+int PyObjectPlus::_setattr_self(const PyAttributeDef attrlist[], void *self, const char *attr, PyObject *value)
{
const PyAttributeDef *attrdef;
void *undoBuffer = NULL;
@@ -247,7 +247,7 @@ int PyObjectPlus::_setattr_self(const PyAttributeDef attrlist[], void *self, con
for (attrdef=attrlist; attrdef->m_name != NULL; attrdef++)
{
- if (attr == attrdef->m_name)
+ if (!strcmp(attr, attrdef->m_name))
{
if (attrdef->m_access == KX_PYATTRIBUTE_RO ||
attrdef->m_type == KX_PYATTRIBUTE_TYPE_DUMMY)
@@ -688,23 +688,54 @@ bool PyObjectPlus::isA(const char *mytypename) // check typename of each parent
for (P = Ps[i=0]; P != NULL; P = Ps[i++])
{
- if (STR_String(P->tp_name) == STR_String(mytypename) )
+ if (strcmp(P->tp_name, mytypename)==0)
return true;
}
return false;
}
-PyObject *PyObjectPlus::Py_isA(PyObject *args) // Python wrapper for isA
+PyObject *PyObjectPlus::Py_isA(PyObject *value) // Python wrapper for isA
{
- char *mytypename;
- if (!PyArg_ParseTuple(args, "s", &mytypename))
+ if (!PyString_Check(value)) {
+ PyErr_SetString(PyExc_TypeError, "expected a string");
return NULL;
- if(isA(mytypename))
+ }
+ if(isA(PyString_AsString(value)))
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
}
+/* Utility function called by the macro _getattr_up()
+ * for getting ob.__dict__() values from our PyObject
+ * this is used by python for doing dir() on an object, so its good
+ * if we return a list of attributes and methods.
+ *
+ * Other then making dir() useful the value returned from __dict__() is not useful
+ * since every value is a Py_None
+ * */
+PyObject *_getattr_dict(PyObject *pydict, PyMethodDef *meth, PyAttributeDef *attrdef)
+{
+ if(pydict==NULL) { /* incase calling __dict__ on the parent of this object raised an error */
+ PyErr_Clear();
+ pydict = PyDict_New();
+ }
+
+ if(meth) {
+ for (; meth->ml_name != NULL; meth++) {
+ PyDict_SetItemString(pydict, meth->ml_name, Py_None);
+ }
+ }
+
+ if(attrdef) {
+ for (; attrdef->m_name != NULL; attrdef++) {
+ PyDict_SetItemString(pydict, attrdef->m_name, Py_None);
+ }
+ }
+
+ return pydict;
+}
+
#endif //NO_EXP_PYTHON_EMBEDDING
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
index e0e2213d984..1a5f50a3d23 100644
--- a/source/gameengine/Expressions/PyObjectPlus.h
+++ b/source/gameengine/Expressions/PyObjectPlus.h
@@ -72,11 +72,8 @@ typedef int Py_ssize_t;
#define PY_METHODCHAR const char *
#endif
- // some basic python macros
-#define Py_Return { Py_INCREF(Py_None); return Py_None;}
-
static inline void Py_Fatal(const char *M) {
- //cout << M << endl;
+ fprintf(stderr, "%s\n", M);
exit(-1);
};
@@ -92,35 +89,22 @@ static inline void Py_Fatal(const char *M) {
virtual PyParentObject *GetParents(void) {return Parents;}
+
// This defines the _getattr_up macro
// which allows attribute and method calls
// to be properly passed up the hierarchy.
#define _getattr_up(Parent) \
- PyObject *rvalue = NULL; \
- if (attr=="__methods__") { \
- PyObject *_attr_string = NULL; \
- PyMethodDef *meth = Methods; \
- rvalue = Parent::_getattr(attr); \
- if (rvalue==NULL) { \
- PyErr_Clear(); \
- rvalue = PyList_New(0); \
- } \
- if (meth) { \
- for (; meth->ml_name != NULL; meth++) { \
- _attr_string = PyString_FromString(meth->ml_name); \
- PyList_Append(rvalue, _attr_string); \
- Py_DECREF(_attr_string); \
- } \
+ PyObject *rvalue = Py_FindMethod(Methods, this, attr); \
+ \
+ if (rvalue == NULL) { \
+ PyErr_Clear(); \
+ rvalue = Parent::_getattr(attr); \
} \
- } else { \
- rvalue = Py_FindMethod(Methods, this, const_cast<char*>(attr.ReadPtr())); \
- if (rvalue == NULL) { \
- PyErr_Clear(); \
- rvalue = Parent::_getattr(attr); \
- } \
- } \
- return rvalue; \
-
+ if ((rvalue == NULL) && !strcmp(attr, "__dict__")) {\
+ PyErr_Clear(); \
+ rvalue = _getattr_dict(Parent::_getattr(attr), Methods, Attributes); \
+ } \
+ return rvalue; \
/**
* These macros are helpfull when embedding Python routines. The second
@@ -283,10 +267,17 @@ typedef struct KX_PYATTRIBUTE_DEF {
#define KX_PYATTRIBUTE_SHORT_RO(name,object,field) \
{ name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL} }
#define KX_PYATTRIBUTE_SHORT_ARRAY_RW(name,min,max,clamp,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL} }
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL} }
#define KX_PYATTRIBUTE_SHORT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, {NULL, &((object *)0)->field, NULL, NULL, NULL} }
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, {NULL, ((object *)0)->field, NULL, NULL, NULL} }
#define KX_PYATTRIBUTE_SHORT_ARRAY_RO(name,object,field,length) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, {NULL, ((object *)0)->field, NULL, NULL, NULL} }
+// SHORT_LIST
+#define KX_PYATTRIBUTE_SHORT_LIST_RW(name,min,max,clamp,object,field,length) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
+ { name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, {NULL, &((object *)0)->field, NULL, NULL, NULL} }
+#define KX_PYATTRIBUTE_SHORT_LIST_RO(name,object,field,length) \
{ name, KX_PYATTRIBUTE_TYPE_SHORT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, {NULL, &((object *)0)->field, NULL, NULL, NULL} }
#define KX_PYATTRIBUTE_INT_RW(name,min,max,clamp,object,field) \
@@ -296,10 +287,17 @@ typedef struct KX_PYATTRIBUTE_DEF {
#define KX_PYATTRIBUTE_INT_RO(name,object,field) \
{ name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL} }
#define KX_PYATTRIBUTE_INT_ARRAY_RW(name,min,max,clamp,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL} }
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL} }
#define KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK(name,min,max,clamp,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, {NULL, NULL, &((object *)0)->field, NULL, NULL} }
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, {NULL, NULL, ((object *)0)->field, NULL, NULL} }
#define KX_PYATTRIBUTE_INT_ARRAY_RO(name,object,field,length) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, {NULL, NULL, ((object *)0)->field, NULL, NULL} }
+// INT_LIST
+#define KX_PYATTRIBUTE_INT_LIST_RW(name,min,max,clamp,object,field,length) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_LIST_RW_CHECK(name,min,max,clamp,object,field,length,function) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, {NULL, NULL, &((object *)0)->field, NULL, NULL} }
+#define KX_PYATTRIBUTE_INT_LIST_RO(name,object,field,length) \
{ name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, {NULL, NULL, &((object *)0)->field, NULL, NULL} }
// always clamp for float
@@ -310,11 +308,11 @@ typedef struct KX_PYATTRIBUTE_DEF {
#define KX_PYATTRIBUTE_FLOAT_RO(name,object,field) \
{ name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL} }
#define KX_PYATTRIBUTE_FLOAT_ARRAY_RW(name,min,max,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, length, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL} }
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, length, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL} }
#define KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK(name,min,max,object,field,length,function) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, length, &object::function, {NULL, NULL, NULL, &((object *)0)->field, NULL} }
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RW, 0, 0, min, max, true, offsetof(object,field), 0, length, &object::function, {NULL, NULL, NULL, ((object *)0)->field, NULL} }
#define KX_PYATTRIBUTE_FLOAT_ARRAY_RO(name,object,field,length) \
- { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, {NULL, NULL, NULL, &((object *)0)->field, NULL} }
+ { name, KX_PYATTRIBUTE_TYPE_FLOAT, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, length, NULL, {NULL, NULL, NULL, ((object *)0)->field, NULL} }
#define KX_PYATTRIBUTE_STRING_RW(name,min,max,clamp,object,field) \
{ name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, 1, NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field} }
@@ -323,6 +321,10 @@ typedef struct KX_PYATTRIBUTE_DEF {
#define KX_PYATTRIBUTE_STRING_RO(name,object,field) \
{ name, KX_PYATTRIBUTE_TYPE_STRING, KX_PYATTRIBUTE_RO, 0, 0, 0.f, 0.f, false, offsetof(object,field), 0, 1 , NULL, {NULL, NULL, NULL, NULL, &((object *)0)->field} }
+//Multiple integer
+#define KX_PYATTRIBUTE_MINT_RW_CHECK(name,min,max,clamp,object,field,length,function) \
+ { name, KX_PYATTRIBUTE_TYPE_INT, KX_PYATTRIBUTE_RW, min, max, 0.f, 0.f, clamp, offsetof(object,field), 0, length, &object::function, {NULL, NULL, &((object *)0)->field, NULL, NULL} }
+
/*------------------------------
* PyObjectPlus
------------------------------*/
@@ -348,23 +350,23 @@ public:
// Py_DECREF(this);
// }; // decref method
- virtual PyObject *_getattr(const STR_String& attr); // _getattr method
+ virtual PyObject *_getattr(const char *attr); // _getattr method
static PyObject *__getattr(PyObject * PyObj, char *attr) // This should be the entry in Type.
{
- return ((PyObjectPlus*) PyObj)->_getattr(STR_String(attr));
+ return ((PyObjectPlus*) PyObj)->_getattr(attr);
}
- static PyObject *_getattr_self(const PyAttributeDef attrlist[], void *self, const STR_String &attr);
- static int _setattr_self(const PyAttributeDef attrlist[], void *self, const STR_String &attr, PyObject *value);
+ static PyObject *_getattr_self(const PyAttributeDef attrlist[], void *self, const char *attr);
+ static int _setattr_self(const PyAttributeDef attrlist[], void *self, const char *attr, PyObject *value);
- virtual int _delattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value); // _setattr method
+ virtual int _delattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value); // _setattr method
static int __setattr(PyObject *PyObj, // This should be the entry in Type.
char *attr,
PyObject *value)
{
if (!value)
return ((PyObjectPlus*) PyObj)->_delattr(attr);
- return ((PyObjectPlus*) PyObj)->_setattr(STR_String(attr), value);
+ return ((PyObjectPlus*) PyObj)->_setattr(attr, value);
}
virtual PyObject *_repr(void); // _repr method
@@ -376,13 +378,15 @@ public:
// isA methods
bool isA(PyTypeObject *T);
bool isA(const char *mytypename);
- PyObject *Py_isA(PyObject *args);
- static PyObject *sPy_isA(PyObject *self, PyObject *args, PyObject *kwd)
+ PyObject *Py_isA(PyObject *value);
+ static PyObject *sPy_isA(PyObject *self, PyObject *value)
{
- return ((PyObjectPlus*)self)->Py_isA(args);
+ return ((PyObjectPlus*)self)->Py_isA(value);
}
};
+PyObject *_getattr_dict(PyObject *pydict, PyMethodDef *meth, PyAttributeDef *attrdef);
+
#endif // _adr_py_lib_h_
#endif //NO_EXP_PYTHON_EMBEDDING
diff --git a/source/gameengine/Expressions/SConscript b/source/gameengine/Expressions/SConscript
index f391afec60b..25adcf3e895 100644
--- a/source/gameengine/Expressions/SConscript
+++ b/source/gameengine/Expressions/SConscript
@@ -6,4 +6,9 @@ sources = env.Glob('*.cpp')
incs ='. #source/kernel/gen_system #intern/string #intern/moto/include'
incs += ' ' + env['BF_PYTHON_INC']
-env.BlenderLib ( 'bf_expressions', sources, Split(incs), [], libtype=['core','player'], priority = [310,120] )
+cxxflags = []
+if env['OURPLATFORM']=='win32-vc':
+ cxxflags.append ('/GR')
+ cxxflags.append ('/O2')
+
+env.BlenderLib ( 'bf_expressions', sources, Split(incs), [], libtype=['core','player'], priority = [360,120], cxx_compileflags=cxxflags)
diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp
index f2b5569c76e..ebb12636ac2 100644
--- a/source/gameengine/Expressions/Value.cpp
+++ b/source/gameengine/Expressions/Value.cpp
@@ -52,6 +52,10 @@ PyObject* cvalue_div(PyObject*v, PyObject*w)
{
return ((CValue*)v)->Calc(VALUE_DIV_OPERATOR,(CValue*)w);
}
+PyObject* cvalue_mod(PyObject*v, PyObject*w)
+{
+ return ((CValue*)v)->Calc(VALUE_MOD_OPERATOR,(CValue*)w);
+}
PyObject* cvalue_neg(PyObject*v)
{
return ((CValue*)v)->Calc(VALUE_NEG_OPERATOR,(CValue*)v);
@@ -112,7 +116,7 @@ static PyNumberMethods cvalue_as_number = {
(binaryfunc)cvalue_sub, /*nb_subtract*/
(binaryfunc)cvalue_mul, /*nb_multiply*/
(binaryfunc)cvalue_div, /*nb_divide*/
- 0,//(binaryfunc)cvalue_remainder, /*nb_remainder*/
+ (binaryfunc)cvalue_mod, /*nb_remainder*/
0,//(binaryfunc)cvalue_divmod, /*nb_divmod*/
0,//0,//0,//0,//(ternaryfunc)cvalue_pow, /*nb_power*/
(unaryfunc)cvalue_neg, /*nb_negative*/
@@ -257,6 +261,9 @@ STR_String CValue::op2str (VALUE_OPERATOR op)
STR_String opmsg;
switch (op) {
+ case VALUE_MOD_OPERATOR:
+ opmsg = " % ";
+ break;
case VALUE_ADD_OPERATOR:
opmsg = " + ";
break;
@@ -673,10 +680,14 @@ static PyMethodDef CValueMethods[] =
{ NULL,NULL} // Sentinel
};
+PyAttributeDef CValue::Attributes[] = {
+ { NULL } //Sentinel
+};
+
-PyObject* CValue::_getattr(const STR_String& attr)
+PyObject* CValue::_getattr(const char *attr)
{
- CValue* resultattr = FindIdentifier(attr);
+ CValue* resultattr = FindIdentifier(STR_String(attr));
STR_String text;
if (resultattr)
{
@@ -761,26 +772,27 @@ CValue* CValue::ConvertPythonToValue(PyObject* pyobj)
}
-int CValue::_delattr(const STR_String& attr)
+int CValue::_delattr(const char *attr)
{
- if (!RemoveProperty(attr)) /* sets error */
+ if (!RemoveProperty(STR_String(attr))) /* sets error */
return 1;
return 0;
}
-int CValue::_setattr(const STR_String& attr,PyObject* pyobj)
+int CValue::_setattr(const char *attr,PyObject* pyobj)
{
CValue* vallie = ConvertPythonToValue(pyobj);
if (vallie)
{
- CValue* oldprop = GetProperty(attr);
+ STR_String attr_str = attr;
+ CValue* oldprop = GetProperty(attr_str);
if (oldprop)
{
oldprop->SetValue(vallie);
} else
{
- SetProperty(attr,vallie);
+ SetProperty(attr_str, vallie);
}
vallie->Release();
} else
@@ -858,7 +870,42 @@ void CValue::SetDeprecationWarnings(bool ignoreDeprecationWarnings)
void CValue::ShowDeprecationWarning(const char* old_way,const char* new_way)
{
- if (!m_ignore_deprecation_warnings)
+ if (!m_ignore_deprecation_warnings) {
printf("Method %s is deprecated, please use %s instead.\n", old_way, new_way);
+
+ // import sys; print '\t%s:%d' % (sys._getframe(0).f_code.co_filename, sys._getframe(0).f_lineno)
+
+ PyObject *getframe, *frame;
+ PyObject *f_lineno, *f_code, *co_filename;
+
+ getframe = PySys_GetObject("_getframe"); // borrowed
+ if (getframe) {
+ frame = PyObject_CallObject(getframe, NULL);
+ if (frame) {
+ f_lineno= PyObject_GetAttrString(frame, "f_lineno");
+ f_code= PyObject_GetAttrString(frame, "f_code");
+ if (f_lineno && f_code) {
+ co_filename= PyObject_GetAttrString(f_code, "co_filename");
+ if (co_filename) {
+
+ printf("\t%s:%d\n", PyString_AsString(co_filename), (int)PyInt_AsLong(f_lineno));
+
+ Py_DECREF(f_lineno);
+ Py_DECREF(f_code);
+ Py_DECREF(co_filename);
+ Py_DECREF(frame);
+ return;
+ }
+ }
+
+ Py_XDECREF(f_lineno);
+ Py_XDECREF(f_code);
+ Py_DECREF(frame);
+ }
+
+ }
+ PyErr_Clear();
+ printf("\tERROR - Could not access sys._getframe(0).f_lineno or sys._getframe().f_code.co_filename\n");
+ }
}
diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h
index 56a4991af27..caf1064dc32 100644
--- a/source/gameengine/Expressions/Value.h
+++ b/source/gameengine/Expressions/Value.h
@@ -75,6 +75,7 @@
enum VALUE_OPERATOR {
+ VALUE_MOD_OPERATOR, // %
VALUE_ADD_OPERATOR, // +
VALUE_SUB_OPERATOR, // -
VALUE_MUL_OPERATOR, // *
@@ -223,7 +224,7 @@ public:
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
void SpecialRelease()
{
@@ -250,8 +251,8 @@ public:
virtual CValue* ConvertPythonToValue(PyObject* pyobj);
- virtual int _delattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr,PyObject* value);
+ virtual int _delattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject* value);
virtual PyObject* ConvertKeysToPython( void );
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
index e8e29fb2769..c21e5db1410 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
@@ -42,14 +42,14 @@ SCA_Joystick::SCA_Joystick(short int index)
m_axis21(0),
m_prec(3200),
m_buttonnum(-2),
+ m_axismax(-1),
m_hatdir(-2),
+ m_buttonmax(-1),
+ m_hatmax(-1),
m_isinit(0),
m_istrig_axis(0),
m_istrig_button(0),
- m_istrig_hat(0),
- m_axismax(-1),
- m_buttonmax(-1),
- m_hatmax(-1)
+ m_istrig_hat(0)
{
#ifndef DISABLE_SDL
m_private = new PrivateData();
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
index a70830193db..7bf051f2b5c 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
@@ -113,7 +113,10 @@ PyMethodDef SCA_2DFilterActuator::Methods[] = {
{NULL,NULL}
};
+PyAttributeDef SCA_2DFilterActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
-PyObject* SCA_2DFilterActuator::_getattr(const STR_String& attr) {
+PyObject* SCA_2DFilterActuator::_getattr(const char *attr) {
_getattr_up(SCA_IActuator);
}
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
index 7ec07cf5b19..9da0500afff 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.h
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
@@ -38,7 +38,7 @@ public:
virtual bool Update();
virtual CValue* GetReplica();
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
};
#endif
diff --git a/source/gameengine/GameLogic/SCA_ANDController.cpp b/source/gameengine/GameLogic/SCA_ANDController.cpp
index cfc2d25e0ae..b67ef7dabaf 100644
--- a/source/gameengine/GameLogic/SCA_ANDController.cpp
+++ b/source/gameengine/GameLogic/SCA_ANDController.cpp
@@ -137,7 +137,11 @@ PyMethodDef SCA_ANDController::Methods[] = {
{NULL,NULL} //Sentinel
};
-PyObject* SCA_ANDController::_getattr(const STR_String& attr) {
+PyAttributeDef SCA_ANDController::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* SCA_ANDController::_getattr(const char *attr) {
_getattr_up(SCA_IController);
}
diff --git a/source/gameengine/GameLogic/SCA_ANDController.h b/source/gameengine/GameLogic/SCA_ANDController.h
index 376f4a9a876..eba7e1b545a 100644
--- a/source/gameengine/GameLogic/SCA_ANDController.h
+++ b/source/gameengine/GameLogic/SCA_ANDController.h
@@ -48,7 +48,7 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
};
diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
index fae8d2ba5a7..7f8dbef7758 100644
--- a/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.cpp
@@ -161,7 +161,7 @@ PyAttributeDef SCA_ActuatorSensor::Attributes[] = {
{ NULL } //Sentinel
};
-PyObject* SCA_ActuatorSensor::_getattr(const STR_String& attr) {
+PyObject* SCA_ActuatorSensor::_getattr(const char *attr) {
PyObject* object = _getattr_self(Attributes, this, attr);
if (object != NULL)
return object;
@@ -180,7 +180,7 @@ int SCA_ActuatorSensor::CheckActuator(void *self, const PyAttributeDef*)
return 1;
}
-int SCA_ActuatorSensor::_setattr(const STR_String& attr, PyObject *value) {
+int SCA_ActuatorSensor::_setattr(const char *attr, PyObject *value) {
int ret = _setattr_self(Attributes, this, attr, value);
if (ret >= 0)
return ret;
@@ -221,7 +221,7 @@ PyObject* SCA_ActuatorSensor::PySetActuator(PyObject* self, PyObject* args, PyOb
} else {
; /* error: bad actuator name */
}
- Py_Return;
+ Py_RETURN_NONE;
}
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.h b/source/gameengine/GameLogic/SCA_ActuatorSensor.h
index 3d64247461c..75ee08f42d6 100644
--- a/source/gameengine/GameLogic/SCA_ActuatorSensor.h
+++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.h
@@ -61,8 +61,8 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
/* 3. setProperty */
KX_PYMETHOD_DOC(SCA_ActuatorSensor,SetActuator);
diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
index f9fbf2387c4..154f0ad8cef 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
@@ -135,7 +135,11 @@ PyMethodDef SCA_AlwaysSensor::Methods[] = {
{NULL,NULL} //Sentinel
};
-PyObject* SCA_AlwaysSensor::_getattr(const STR_String& attr) {
+PyAttributeDef SCA_AlwaysSensor::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* SCA_AlwaysSensor::_getattr(const char *attr) {
_getattr_up(SCA_ISensor);
}
diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h
index 8bf2a8aa98e..ebe6ba80208 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysSensor.h
+++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h
@@ -52,7 +52,7 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
};
diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.cpp b/source/gameengine/GameLogic/SCA_DelaySensor.cpp
index 4c97ca98d72..31a620b939d 100644
--- a/source/gameengine/GameLogic/SCA_DelaySensor.cpp
+++ b/source/gameengine/GameLogic/SCA_DelaySensor.cpp
@@ -53,10 +53,10 @@ SCA_DelaySensor::SCA_DelaySensor(class SCA_EventManager* eventmgr,
int duration,
bool repeat,
PyTypeObject* T)
- : SCA_ISensor(gameobj,eventmgr, T),
+ : SCA_ISensor(gameobj,eventmgr, T),
+ m_repeat(repeat),
m_delay(delay),
- m_duration(duration),
- m_repeat(repeat)
+ m_duration(duration)
{
Init();
}
@@ -178,14 +178,14 @@ PyAttributeDef SCA_DelaySensor::Attributes[] = {
{ NULL } //Sentinel
};
-PyObject* SCA_DelaySensor::_getattr(const STR_String& attr) {
+PyObject* SCA_DelaySensor::_getattr(const char *attr) {
PyObject* object = _getattr_self(Attributes, this, attr);
if (object != NULL)
return object;
_getattr_up(SCA_ISensor);
}
-int SCA_DelaySensor::_setattr(const STR_String& attr, PyObject *value) {
+int SCA_DelaySensor::_setattr(const char *attr, PyObject *value) {
int ret = _setattr_self(Attributes, this, attr, value);
if (ret >= 0)
return ret;
@@ -211,7 +211,7 @@ PyObject* SCA_DelaySensor::PySetDelay(PyObject* self, PyObject* args, PyObject*
return NULL;
}
m_delay = delay;
- Py_Return;
+ Py_RETURN_NONE;
}
const char SCA_DelaySensor::SetDuration_doc[] =
@@ -233,7 +233,7 @@ PyObject* SCA_DelaySensor::PySetDuration(PyObject* self, PyObject* args, PyObjec
return NULL;
}
m_duration = duration;
- Py_Return;
+ Py_RETURN_NONE;
}
const char SCA_DelaySensor::SetRepeat_doc[] =
@@ -250,7 +250,7 @@ PyObject* SCA_DelaySensor::PySetRepeat(PyObject* self, PyObject* args, PyObject*
return NULL;
}
m_repeat = (repeat != 0);
- Py_Return;
+ Py_RETURN_NONE;
}
const char SCA_DelaySensor::GetDelay_doc[] =
diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.h b/source/gameengine/GameLogic/SCA_DelaySensor.h
index ff3afe16542..491eee61da8 100644
--- a/source/gameengine/GameLogic/SCA_DelaySensor.h
+++ b/source/gameengine/GameLogic/SCA_DelaySensor.h
@@ -60,8 +60,8 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
/* setProperty */
KX_PYMETHOD_DOC(SCA_DelaySensor,SetDelay);
diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.cpp b/source/gameengine/GameLogic/SCA_ExpressionController.cpp
index e9a543c9f31..8ed46beb7f3 100644
--- a/source/gameengine/GameLogic/SCA_ExpressionController.cpp
+++ b/source/gameengine/GameLogic/SCA_ExpressionController.cpp
@@ -49,7 +49,8 @@ SCA_ExpressionController::SCA_ExpressionController(SCA_IObject* gameobj,
const STR_String& exprtext,
PyTypeObject* T)
:SCA_IController(gameobj,T),
- m_exprText(exprtext)
+ m_exprText(exprtext),
+ m_exprCache(NULL)
{
}
@@ -57,6 +58,8 @@ SCA_ExpressionController::SCA_ExpressionController(SCA_IObject* gameobj,
SCA_ExpressionController::~SCA_ExpressionController()
{
+ if (m_exprCache)
+ m_exprCache->Release();
}
@@ -65,6 +68,7 @@ CValue* SCA_ExpressionController::GetReplica()
{
SCA_ExpressionController* replica = new SCA_ExpressionController(*this);
replica->m_exprText = m_exprText;
+ replica->m_exprCache = NULL;
// this will copy properties and so on...
CValue::AddDataToReplica(replica);
@@ -72,18 +76,32 @@ CValue* SCA_ExpressionController::GetReplica()
}
+// Forced deletion of precalculated expression to break reference loop
+// Use this function when you know that you won't use the sensor anymore
+void SCA_ExpressionController::Delete()
+{
+ if (m_exprCache)
+ {
+ m_exprCache->Release();
+ m_exprCache = NULL;
+ }
+ Release();
+}
+
void SCA_ExpressionController::Trigger(SCA_LogicManager* logicmgr)
{
bool expressionresult = false;
-
- CParser parser;
- parser.SetContext(this->AddRef());
- CExpression* expr = parser.ProcessText(m_exprText);
- if (expr)
+ if (!m_exprCache)
+ {
+ CParser parser;
+ parser.SetContext(this->AddRef());
+ m_exprCache = parser.ProcessText(m_exprText);
+ }
+ if (m_exprCache)
{
- CValue* value = expr->Calculate();
+ CValue* value = m_exprCache->Calculate();
if (value)
{
if (value->IsError())
@@ -97,7 +115,8 @@ void SCA_ExpressionController::Trigger(SCA_LogicManager* logicmgr)
value->Release();
}
- expr->Release();
+ //m_exprCache->Release();
+ //m_exprCache = NULL;
}
/*
diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.h b/source/gameengine/GameLogic/SCA_ExpressionController.h
index f1db45a19e0..79c26eea1e7 100644
--- a/source/gameengine/GameLogic/SCA_ExpressionController.h
+++ b/source/gameengine/GameLogic/SCA_ExpressionController.h
@@ -38,6 +38,7 @@ class SCA_ExpressionController : public SCA_IController
{
// Py_Header;
STR_String m_exprText;
+ CExpression* m_exprCache;
public:
SCA_ExpressionController(SCA_IObject* gameobj,
@@ -48,12 +49,17 @@ public:
virtual CValue* GetReplica();
virtual void Trigger(SCA_LogicManager* logicmgr);
virtual CValue* FindIdentifier(const STR_String& identifiername);
+ /**
+ * used to release the expression cache
+ * so that self references are removed before the controller itself is released
+ */
+ virtual void Delete();
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
-// virtual PyObject* _getattr(const STR_String& attr);
+// virtual PyObject* _getattr(const char *attr);
};
diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp
index eeca2d7b44c..309f3108418 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_IActuator.cpp
@@ -36,8 +36,8 @@ using namespace std;
SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj,
PyTypeObject* T) :
- m_links(0),
- SCA_ILogicBrick(gameobj,T)
+ SCA_ILogicBrick(gameobj,T),
+ m_links(0)
{
// nothing to do
}
diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h
index 7ffb21b5490..51bd6454d92 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.h
+++ b/source/gameengine/GameLogic/SCA_IActuator.h
@@ -36,9 +36,9 @@ class SCA_IActuator : public SCA_ILogicBrick
{
friend class SCA_LogicManager;
protected:
- std::vector<CValue*> m_events;
int m_links; // number of active links to controllers
// when 0, the actuator is automatically stopped
+ std::vector<CValue*> m_events;
void RemoveAllEvents();
public:
diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp
index 0bd20117f31..f9c192cae5c 100644
--- a/source/gameengine/GameLogic/SCA_IController.cpp
+++ b/source/gameengine/GameLogic/SCA_IController.cpp
@@ -38,8 +38,8 @@
SCA_IController::SCA_IController(SCA_IObject* gameobj,
PyTypeObject* T)
:
- m_statemask(0),
- SCA_ILogicBrick(gameobj,T)
+ SCA_ILogicBrick(gameobj,T),
+ m_statemask(0)
{
}
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
index 8286c0829a7..49d39f75814 100644
--- a/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.cpp
@@ -278,7 +278,7 @@ int SCA_ILogicBrick::CheckProperty(void *self, const PyAttributeDef *attrdef)
}
PyObject*
-SCA_ILogicBrick::_getattr(const STR_String& attr)
+SCA_ILogicBrick::_getattr(const char *attr)
{
PyObject* object = _getattr_self(Attributes, this, attr);
if (object != NULL)
@@ -286,7 +286,7 @@ SCA_ILogicBrick::_getattr(const STR_String& attr)
_getattr_up(CValue);
}
-int SCA_ILogicBrick::_setattr(const STR_String& attr, PyObject *value)
+int SCA_ILogicBrick::_setattr(const char *attr, PyObject *value)
{
int ret = _setattr_self(Attributes, this, attr, value);
if (ret >= 0)
@@ -324,7 +324,7 @@ PyObject* SCA_ILogicBrick::PySetExecutePriority(PyObject* self,
m_Execute_Ueber_Priority = priority;
- Py_Return;
+ Py_RETURN_NONE;
}
diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h
index 772bd65d577..70d49941613 100644
--- a/source/gameengine/GameLogic/SCA_ILogicBrick.h
+++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h
@@ -62,6 +62,7 @@ public:
SCA_IObject* GetParent();
virtual void ReParent(SCA_IObject* parent);
virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map);
+ virtual void Delete() { Release(); }
// act as a BoolValue (with value IsPositiveTrigger)
virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
@@ -78,8 +79,8 @@ public:
virtual bool LessComparedTo(SCA_ILogicBrick* other);
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
static class SCA_LogicManager* m_sCurrentLogicManager;
diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp
index b0f8decee26..debd62d44e6 100644
--- a/source/gameengine/GameLogic/SCA_IObject.cpp
+++ b/source/gameengine/GameLogic/SCA_IObject.cpp
@@ -40,7 +40,7 @@
MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0);
-SCA_IObject::SCA_IObject(PyTypeObject* T): m_initState(0), m_state(0), CValue(T)
+SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T), m_initState(0), m_state(0)
{
m_suspended = false;
}
@@ -59,7 +59,9 @@ SCA_IObject::~SCA_IObject()
SCA_ControllerList::iterator itc;
for (itc = m_controllers.begin(); !(itc == m_controllers.end()); ++itc)
{
- ((CValue*)(*itc))->Release();
+ //Use Delete for controller to ensure proper cleaning (expression controller)
+ (*itc)->Delete();
+ //((CValue*)(*itc))->Release();
}
SCA_ActuatorList::iterator ita;
for (ita = m_registeredActuators.begin(); !(ita==m_registeredActuators.end()); ++ita)
@@ -407,9 +409,12 @@ PyMethodDef SCA_IObject::Methods[] = {
{NULL,NULL} //Sentinel
};
+PyAttributeDef SCA_IObject::Attributes[] = {
+ { NULL } //Sentinel
+};
-PyObject* SCA_IObject::_getattr(const STR_String& attr) {
+PyObject* SCA_IObject::_getattr(const char *attr) {
_getattr_up(CValue);
}
diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h
index 38a7ed29dca..d47353b1ac0 100644
--- a/source/gameengine/GameLogic/SCA_IObject.h
+++ b/source/gameengine/GameLogic/SCA_IObject.h
@@ -145,7 +145,7 @@ public:
// const class MT_Point3& ConvertPythonPylist(PyObject* pylist);
// here come the python forwarded methods
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
virtual int GetGameObjectType() {return -1;}
diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
index 68a3a93eab0..e8a072f4c46 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -264,7 +264,7 @@ PyObject* SCA_ISensor::PySetUsePosPulseMode(PyObject* self, PyObject* args, PyOb
int pyarg = 0;
if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; }
m_pos_pulsemode = PyArgToBool(pyarg);
- Py_Return;
+ Py_RETURN_NONE;
}
/**
@@ -303,7 +303,7 @@ PyObject* SCA_ISensor::PySetFrequency(PyObject* self, PyObject* args, PyObject*
};
m_pulse_frequency = pulse_frequencyArg;
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -326,7 +326,7 @@ PyObject* SCA_ISensor::PySetInvert(PyObject* self, PyObject* args, PyObject* kwd
int pyarg = 0;
if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; }
m_invert = PyArgToBool(pyarg);
- Py_Return;
+ Py_RETURN_NONE;
}
const char SCA_ISensor::GetLevel_doc[] =
@@ -352,7 +352,7 @@ PyObject* SCA_ISensor::PySetLevel(PyObject* self, PyObject* args, PyObject* kwds
int pyarg = 0;
if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; }
m_level = PyArgToBool(pyarg);
- Py_Return;
+ Py_RETURN_NONE;
}
const char SCA_ISensor::GetUseNegPulseMode_doc[] =
@@ -375,7 +375,7 @@ PyObject* SCA_ISensor::PySetUseNegPulseMode(PyObject* self, PyObject* args, PyOb
int pyarg = 0;
if(!PyArg_ParseTuple(args, "i", &pyarg)) { return NULL; }
m_neg_pulsemode = PyArgToBool(pyarg);
- Py_Return;
+ Py_RETURN_NONE;
}
//<------Deprecated
@@ -385,7 +385,7 @@ KX_PYMETHODDEF_DOC_NOARGS(SCA_ISensor, reset,
"\tThe sensor is put in its initial state as if it was just activated.\n")
{
Init();
- Py_Return;
+ Py_RETURN_NONE;
}
/* ----------------------------------------------- */
@@ -461,19 +461,19 @@ PyAttributeDef SCA_ISensor::Attributes[] = {
};
PyObject*
-SCA_ISensor::_getattr(const STR_String& attr)
+SCA_ISensor::_getattr(const char *attr)
{
PyObject* object = _getattr_self(Attributes, this, attr);
if (object != NULL)
return object;
- if (attr == "triggered")
+ if (!strcmp(attr, "triggered"))
{
int retval = 0;
if (SCA_PythonController::m_sCurrentController)
retval = SCA_PythonController::m_sCurrentController->IsTriggered(this);
return PyInt_FromLong(retval);
}
- if (attr == "positive")
+ if (!strcmp(attr, "positive"))
{
int retval = IsPositiveTrigger();
return PyInt_FromLong(retval);
@@ -481,7 +481,7 @@ SCA_ISensor::_getattr(const STR_String& attr)
_getattr_up(SCA_ILogicBrick);
}
-int SCA_ISensor::_setattr(const STR_String& attr, PyObject *value)
+int SCA_ISensor::_setattr(const char *attr, PyObject *value)
{
int ret = _setattr_self(Attributes, this, attr, value);
if (ret >= 0)
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
index 1b57c4621e4..23f2c76c19f 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.h
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -105,11 +105,6 @@ public:
bool negmode,
int freq);
- /** Release sensor
- * For property sensor, it is used to release the pre-calculated expression
- * so that self references are removed before the sensor itself is released
- */
- virtual void Delete() { Release(); }
/** Set inversion of pulses on or off. */
void SetInvert(bool inv);
/** set the level detection on or off */
@@ -141,8 +136,8 @@ public:
/* Python functions: */
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
//Deprecated functions ----->
KX_PYMETHOD_DOC_NOARGS(SCA_ISensor,IsPositive);
diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
index 694bca9bac5..c2d90c830cf 100644
--- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
@@ -331,8 +331,8 @@ PyAttributeDef SCA_JoystickSensor::Attributes[] = {
KX_PYATTRIBUTE_SHORT_RW("index",0,JOYINDEX_MAX-1,true,SCA_JoystickSensor,m_joyindex),
KX_PYATTRIBUTE_INT_RW("threshold",0,32768,true,SCA_JoystickSensor,m_precision),
KX_PYATTRIBUTE_INT_RW("button",0,100,false,SCA_JoystickSensor,m_button),
- KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK("axis",0,3,true,SCA_JoystickSensor,m_axis,2,CheckAxis),
- KX_PYATTRIBUTE_INT_ARRAY_RW_CHECK("hat",0,12,true,SCA_JoystickSensor,m_hat,2,CheckHat),
+ KX_PYATTRIBUTE_INT_LIST_RW_CHECK("axis",0,3,true,SCA_JoystickSensor,m_axis,2,CheckAxis),
+ KX_PYATTRIBUTE_INT_LIST_RW_CHECK("hat",0,12,true,SCA_JoystickSensor,m_hat,2,CheckHat),
// dummy attributes will just be read-only in _setattr
// you still need to defined them in _getattr
KX_PYATTRIBUTE_DUMMY("axisPosition"),
@@ -343,24 +343,24 @@ PyAttributeDef SCA_JoystickSensor::Attributes[] = {
{ NULL } //Sentinel
};
-PyObject* SCA_JoystickSensor::_getattr(const STR_String& attr) {
+PyObject* SCA_JoystickSensor::_getattr(const char *attr) {
SCA_Joystick *joy = m_pJoystickMgr->GetJoystickDevice(m_joyindex);
- if (attr == "axisPosition") {
+ if (!strcmp(attr, "axisPosition")) {
if(joy)
return Py_BuildValue("[iiii]", joy->GetAxis10(), joy->GetAxis11(), joy->GetAxis20(), joy->GetAxis21());
else
return Py_BuildValue("[iiii]", 0, 0, 0, 0);
}
- if (attr == "numAxis") {
+ if (!strcmp(attr, "numAxis")) {
return PyInt_FromLong( joy ? joy->GetNumberOfAxes() : 0 );
}
- if (attr == "numButtons") {
+ if (!strcmp(attr, "numButtons")) {
return PyInt_FromLong( joy ? joy->GetNumberOfButtons() : 0 );
}
- if (attr == "numHats") {
+ if (!strcmp(attr, "numHats")) {
return PyInt_FromLong( joy ? joy->GetNumberOfHats() : 0 );
}
- if (attr == "connected") {
+ if (!strcmp(attr, "connected")) {
return PyBool_FromLong( joy ? joy->Connected() : 0 );
}
PyObject* object = _getattr_self(Attributes, this, attr);
@@ -369,7 +369,7 @@ PyObject* SCA_JoystickSensor::_getattr(const STR_String& attr) {
_getattr_up(SCA_ISensor);
}
-int SCA_JoystickSensor::_setattr(const STR_String& attr, PyObject *value)
+int SCA_JoystickSensor::_setattr(const char *attr, PyObject *value)
{
int ret = _setattr_self(Attributes, this, attr, value);
if (ret >= 0)
diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h
index fa11f1cc3d0..49d220c056d 100644
--- a/source/gameengine/GameLogic/SCA_JoystickSensor.h
+++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h
@@ -121,8 +121,8 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
/* Joystick Index */
KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetIndex);
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
index 981d165287b..324e5eae98a 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
@@ -577,7 +577,7 @@ PyObject* SCA_KeyboardSensor::PySetKey(PyObject* self, PyObject* args, PyObject*
/* anything. It's up to the user to provide a sensible number. */
m_hotkey = keyCode;
- Py_Return;
+ Py_RETURN_NONE;
}
/** 3. GetHold1 : set the first bucky bit */
@@ -609,7 +609,7 @@ PyObject* SCA_KeyboardSensor::PySetHold1(PyObject* self, PyObject* args, PyObjec
/* anything. It's up to the user to provide a sensible number. */
m_qual = keyCode;
- Py_Return;
+ Py_RETURN_NONE;
}
/** 5. GetHold2 : get the second bucky bit */
@@ -641,7 +641,7 @@ PyObject* SCA_KeyboardSensor::PySetHold2(PyObject* self, PyObject* args, PyObjec
/* anything. It's up to the user to provide a sensible number. */
m_qual2 = keyCode;
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -682,7 +682,7 @@ PyObject* SCA_KeyboardSensor::PyGetPressedKeys(PyObject* self, PyObject* args, P
if (index>0) return resultlist;
}
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -725,7 +725,7 @@ SCA_IInputDevice* inputdev = m_pKeyboardMgr->GetInputDevice();
if (index > 0) return resultlist;
}
- Py_Return;
+ Py_RETURN_NONE;
}
//<---- Deprecated
@@ -770,7 +770,7 @@ KX_PYMETHODDEF_DOC_O(SCA_KeyboardSensor, getKeyStatus,
return PyInt_FromLong(inevent.m_status);
}
- Py_Return;
+ Py_RETURN_NONE;
}
/* ------------------------------------------------------------------------- */
@@ -831,7 +831,7 @@ PyAttributeDef SCA_KeyboardSensor::Attributes[] = {
};
PyObject*
-SCA_KeyboardSensor::_getattr(const STR_String& attr)
+SCA_KeyboardSensor::_getattr(const char *attr)
{
PyObject* object = _getattr_self(Attributes, this, attr);
if (object != NULL)
@@ -839,7 +839,7 @@ SCA_KeyboardSensor::_getattr(const STR_String& attr)
_getattr_up(SCA_ISensor);
}
-int SCA_KeyboardSensor::_setattr(const STR_String& attr, PyObject *value)
+int SCA_KeyboardSensor::_setattr(const char *attr, PyObject *value)
{
int ret = _setattr_self(Attributes, this, attr, value);
if (ret >= 0)
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
index 4efbe9366cc..bc2f86327a5 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
@@ -126,8 +126,8 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
//Deprecated functions ----->
/** 1. GetKey : check which key this sensor looks at */
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
index 09b46e6443e..57535b29f32 100644
--- a/source/gameengine/GameLogic/SCA_MouseSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
@@ -158,8 +158,8 @@ bool SCA_MouseSensor::Evaluate(CValue* event)
case KX_MOUSESENSORMODE_WHEELUP:
case KX_MOUSESENSORMODE_WHEELDOWN:
{
- const SCA_InputEvent& event = mousedev->GetEventValue(m_hotkey);
- switch (event.m_status){
+ const SCA_InputEvent& mevent = mousedev->GetEventValue(m_hotkey);
+ switch (mevent.m_status){
case SCA_InputEvent::KX_JUSTACTIVATED:
m_val = 1;
result = true;
@@ -282,7 +282,7 @@ KX_PYMETHODDEF_DOC_O(SCA_MouseSensor, getButtonStatus,
int button = PyInt_AsLong(value);
if ((button < SCA_IInputDevice::KX_LEFTMOUSE)
- || (button > SCA_IInputDevice::KX_MIDDLEMOUSE)){
+ || (button > SCA_IInputDevice::KX_RIGHTMOUSE)){
PyErr_SetString(PyExc_ValueError, "invalid button specified!");
return NULL;
}
@@ -292,7 +292,7 @@ KX_PYMETHODDEF_DOC_O(SCA_MouseSensor, getButtonStatus,
return PyInt_FromLong(event.m_status);
}
- Py_Return;
+ Py_RETURN_NONE;
}
/* ------------------------------------------------------------------------- */
@@ -337,11 +337,11 @@ PyMethodDef SCA_MouseSensor::Methods[] = {
PyAttributeDef SCA_MouseSensor::Attributes[] = {
KX_PYATTRIBUTE_SHORT_RW_CHECK("mode",KX_MOUSESENSORMODE_NODEF,KX_MOUSESENSORMODE_MAX-1,true,SCA_MouseSensor,m_mousemode,UpdateHotkey),
- KX_PYATTRIBUTE_SHORT_ARRAY_RO("position",SCA_MouseSensor,m_x,2),
+ KX_PYATTRIBUTE_SHORT_LIST_RO("position",SCA_MouseSensor,m_x,2),
{ NULL } //Sentinel
};
-PyObject* SCA_MouseSensor::_getattr(const STR_String& attr)
+PyObject* SCA_MouseSensor::_getattr(const char *attr)
{
PyObject* object = _getattr_self(Attributes, this, attr);
if (object != NULL)
@@ -349,7 +349,7 @@ PyObject* SCA_MouseSensor::_getattr(const STR_String& attr)
_getattr_up(SCA_ISensor);
}
-int SCA_MouseSensor::_setattr(const STR_String& attr, PyObject *value)
+int SCA_MouseSensor::_setattr(const char *attr, PyObject *value)
{
int ret = _setattr_self(Attributes, this, attr, value);
if (ret >= 0)
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h
index 82af2ce9c04..30b43fe53cc 100644
--- a/source/gameengine/GameLogic/SCA_MouseSensor.h
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.h
@@ -109,8 +109,8 @@ class SCA_MouseSensor : public SCA_ISensor
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
//Deprecated functions ----->
/* read x-coordinate */
diff --git a/source/gameengine/GameLogic/SCA_NANDController.cpp b/source/gameengine/GameLogic/SCA_NANDController.cpp
index 5b869ee8298..18426d75582 100644
--- a/source/gameengine/GameLogic/SCA_NANDController.cpp
+++ b/source/gameengine/GameLogic/SCA_NANDController.cpp
@@ -137,7 +137,11 @@ PyMethodDef SCA_NANDController::Methods[] = {
{NULL,NULL} //Sentinel
};
-PyObject* SCA_NANDController::_getattr(const STR_String& attr) {
+PyAttributeDef SCA_NANDController::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* SCA_NANDController::_getattr(const char *attr) {
_getattr_up(SCA_IController);
}
diff --git a/source/gameengine/GameLogic/SCA_NANDController.h b/source/gameengine/GameLogic/SCA_NANDController.h
index 1193ff64f07..d88504cfc0d 100644
--- a/source/gameengine/GameLogic/SCA_NANDController.h
+++ b/source/gameengine/GameLogic/SCA_NANDController.h
@@ -48,7 +48,7 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
};
diff --git a/source/gameengine/GameLogic/SCA_NORController.cpp b/source/gameengine/GameLogic/SCA_NORController.cpp
index 2866dec0b74..1de6a641c3d 100644
--- a/source/gameengine/GameLogic/SCA_NORController.cpp
+++ b/source/gameengine/GameLogic/SCA_NORController.cpp
@@ -137,7 +137,11 @@ PyMethodDef SCA_NORController::Methods[] = {
{NULL,NULL} //Sentinel
};
-PyObject* SCA_NORController::_getattr(const STR_String& attr) {
+PyAttributeDef SCA_NORController::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* SCA_NORController::_getattr(const char *attr) {
_getattr_up(SCA_IController);
}
diff --git a/source/gameengine/GameLogic/SCA_NORController.h b/source/gameengine/GameLogic/SCA_NORController.h
index aab59e3d46c..45b639f3f3f 100644
--- a/source/gameengine/GameLogic/SCA_NORController.h
+++ b/source/gameengine/GameLogic/SCA_NORController.h
@@ -48,7 +48,7 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
};
diff --git a/source/gameengine/GameLogic/SCA_ORController.cpp b/source/gameengine/GameLogic/SCA_ORController.cpp
index 2d4eb31f241..61fbc889d90 100644
--- a/source/gameengine/GameLogic/SCA_ORController.cpp
+++ b/source/gameengine/GameLogic/SCA_ORController.cpp
@@ -129,7 +129,12 @@ PyMethodDef SCA_ORController::Methods[] = {
{NULL,NULL} //Sentinel
};
-PyObject* SCA_ORController::_getattr(const STR_String& attr) {
+PyAttributeDef SCA_ORController::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+
+PyObject* SCA_ORController::_getattr(const char *attr) {
_getattr_up(SCA_IController);
}
diff --git a/source/gameengine/GameLogic/SCA_ORController.h b/source/gameengine/GameLogic/SCA_ORController.h
index beb69aa2af9..9a6e9e75022 100644
--- a/source/gameengine/GameLogic/SCA_ORController.h
+++ b/source/gameengine/GameLogic/SCA_ORController.h
@@ -49,7 +49,7 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
};
#endif //__KX_ORCONTROLLER
diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
index 566d3b63487..c9ace081bae 100644
--- a/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
@@ -260,14 +260,14 @@ PyAttributeDef SCA_PropertyActuator::Attributes[] = {
{ NULL } //Sentinel
};
-PyObject* SCA_PropertyActuator::_getattr(const STR_String& attr) {
+PyObject* SCA_PropertyActuator::_getattr(const char *attr) {
PyObject* object = _getattr_self(Attributes, this, attr);
if (object != NULL)
return object;
_getattr_up(SCA_IActuator);
}
-int SCA_PropertyActuator::_setattr(const STR_String& attr, PyObject *value) {
+int SCA_PropertyActuator::_setattr(const char *attr, PyObject *value) {
int ret = _setattr_self(Attributes, this, attr, value);
if (ret >= 0)
return ret;
@@ -298,7 +298,7 @@ PyObject* SCA_PropertyActuator::PySetProperty(PyObject* self, PyObject* args, Py
}
prop->Release();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 2. getProperty */
@@ -328,7 +328,7 @@ PyObject* SCA_PropertyActuator::PySetValue(PyObject* self, PyObject* args, PyObj
if (valArg) m_exprtxt = valArg;
- Py_Return;
+ Py_RETURN_NONE;
}
/* 4. getValue */
diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.h b/source/gameengine/GameLogic/SCA_PropertyActuator.h
index cdfeee4c67d..444d9285796 100644
--- a/source/gameengine/GameLogic/SCA_PropertyActuator.h
+++ b/source/gameengine/GameLogic/SCA_PropertyActuator.h
@@ -85,8 +85,8 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
// python wrapped methods
KX_PYMETHOD_DOC(SCA_PropertyActuator,SetProperty);
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
index a6f7a9cd82b..d683c8bb3e7 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
@@ -352,14 +352,14 @@ PyAttributeDef SCA_PropertySensor::Attributes[] = {
};
-PyObject* SCA_PropertySensor::_getattr(const STR_String& attr) {
+PyObject* SCA_PropertySensor::_getattr(const char *attr) {
PyObject* object = _getattr_self(Attributes, this, attr);
if (object != NULL)
return object;
_getattr_up(SCA_ISensor); /* implicit return! */
}
-int SCA_PropertySensor::_setattr(const STR_String& attr, PyObject *value) {
+int SCA_PropertySensor::_setattr(const char *attr, PyObject *value) {
int ret = _setattr_self(Attributes, this, attr, value);
if (ret >= 0)
return ret;
@@ -397,7 +397,7 @@ PyObject* SCA_PropertySensor::PySetType(PyObject* self, PyObject* args, PyObject
m_checktype = typeArg;
}
- Py_Return;
+ Py_RETURN_NONE;
}
/* 3. getProperty */
@@ -434,7 +434,7 @@ PyObject* SCA_PropertySensor::PySetProperty(PyObject* self, PyObject* args, PyOb
; /* error: bad property name */
}
prop->Release();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 5. getValue */
@@ -470,7 +470,7 @@ PyObject* SCA_PropertySensor::PySetValue(PyObject* self, PyObject* args, PyObjec
m_checkpropval = oldval;
return NULL;
}
- Py_Return;
+ Py_RETURN_NONE;
}
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h
index e625e84a36f..2594e3fca9d 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.h
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.h
@@ -70,6 +70,10 @@ public:
KX_PROPSENSOR_TYPE checktype,
PyTypeObject* T=&Type );
+ /**
+ * For property sensor, it is used to release the pre-calculated expression
+ * so that self references are removed before the sensor itself is released
+ */
virtual void Delete();
virtual ~SCA_PropertySensor();
virtual CValue* GetReplica();
@@ -85,8 +89,8 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
/* 1. getType */
KX_PYMETHOD_DOC(SCA_PropertySensor,GetType);
diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp
index e879481a444..c75e36acab2 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.cpp
+++ b/source/gameengine/GameLogic/SCA_PythonController.cpp
@@ -157,8 +157,40 @@ static const char* sPyGetCurrentController__doc__;
PyObject* SCA_PythonController::sPyGetCurrentController(PyObject* self)
{
- m_sCurrentController->AddRef();
- return m_sCurrentController;
+ return m_sCurrentController->AddRef();
+}
+
+SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value)
+{
+ // for safety, todo: only allow for registered actuators (pointertable)
+ // we don't want to crash gameengine/blender by python scripts
+ std::vector<SCA_IActuator*> lacts = m_sCurrentController->GetLinkedActuators();
+ std::vector<SCA_IActuator*>::iterator it;
+
+ if (PyString_Check(value)) {
+ /* get the actuator from the name */
+ char *name= PyString_AsString(value);
+ for(it = lacts.begin(); it!= lacts.end(); it++) {
+ if( name == (*it)->GetName() ) {
+ return *it;
+ }
+ }
+ }
+ else {
+ /* Expecting an actuator type */
+ for(it = lacts.begin(); it!= lacts.end(); it++) {
+ if( static_cast<SCA_IActuator*>(value) == (*it) ) {
+ return *it;
+ }
+ }
+ }
+
+ /* set the exception */
+ PyObject *value_str = PyObject_Repr(value); /* new ref */
+ PyErr_Format(PyExc_ValueError, "'%s' not in this controllers actuator list", PyString_AsString(value_str));
+ Py_DECREF(value_str);
+
+ return false;
}
#if 0
@@ -175,26 +207,14 @@ PyObject* SCA_PythonController::sPyAddActiveActuator(
int activate;
if (!PyArg_ParseTuple(args, "Oi", &ob1,&activate))
return NULL;
-
- // for safety, todo: only allow for registered actuators (pointertable)
- // we don't want to crash gameengine/blender by python scripts
- std::vector<SCA_IActuator*> lacts = m_sCurrentController->GetLinkedActuators();
- std::vector<SCA_IActuator*>::iterator it;
- bool found = false;
- CValue* act = (CValue*)ob1;
-
- for(it = lacts.begin(); it!= lacts.end(); it++) {
- if( static_cast<SCA_IActuator*>(act) == (*it) ) {
- found=true;
- break;
- }
- }
- if(found){
- CValue* boolval = new CBoolValue(activate!=0);
- m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)act,boolval);
- boolval->Release();
- }
+ SCA_IActuator* actu = LinkedActuatorFromPy(ob1);
+ if(actu==NULL)
+ return NULL;
+
+ CValue* boolval = new CBoolValue(activate!=0);
+ m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu,boolval);
+ boolval->Release();
Py_RETURN_NONE;
}
@@ -229,18 +249,61 @@ PyParentObject SCA_PythonController::Parents[] = {
NULL
};
PyMethodDef SCA_PythonController::Methods[] = {
+ {"activate", (PyCFunction) SCA_PythonController::sPyActivate, METH_O},
+ {"deactivate", (PyCFunction) SCA_PythonController::sPyDeActivate, METH_O},
+
{"getActuators", (PyCFunction) SCA_PythonController::sPyGetActuators, METH_NOARGS, (PY_METHODCHAR)SCA_PythonController::GetActuators_doc},
{"getActuator", (PyCFunction) SCA_PythonController::sPyGetActuator, METH_O, (PY_METHODCHAR)SCA_PythonController::GetActuator_doc},
{"getSensors", (PyCFunction) SCA_PythonController::sPyGetSensors, METH_NOARGS, (PY_METHODCHAR)SCA_PythonController::GetSensors_doc},
{"getSensor", (PyCFunction) SCA_PythonController::sPyGetSensor, METH_O, (PY_METHODCHAR)SCA_PythonController::GetSensor_doc},
- {"setScript", (PyCFunction) SCA_PythonController::sPySetScript, METH_O},
//Deprecated functions ------>
+ {"setScript", (PyCFunction) SCA_PythonController::sPySetScript, METH_O},
{"getScript", (PyCFunction) SCA_PythonController::sPyGetScript, METH_NOARGS},
{"getState", (PyCFunction) SCA_PythonController::sPyGetState, METH_NOARGS},
//<----- Deprecated
{NULL,NULL} //Sentinel
};
+PyAttributeDef SCA_PythonController::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+bool SCA_PythonController::Compile()
+{
+ //printf("py script modified '%s'\n", m_scriptName.Ptr());
+
+ // if a script already exists, decref it before replace the pointer to a new script
+ if (m_bytecode)
+ {
+ Py_DECREF(m_bytecode);
+ m_bytecode=NULL;
+ }
+ // recompile the scripttext into bytecode
+ m_bytecode = Py_CompileString(m_scriptText.Ptr(), m_scriptName.Ptr(), Py_file_input);
+ m_bModified=false;
+
+ if (m_bytecode)
+ {
+
+ return true;
+ }
+ else {
+ // didn't compile, so instead of compile, complain
+ // something is wrong, tell the user what went wrong
+ printf("Python compile error from controller \"%s\": \n", GetName().Ptr());
+ //PyRun_SimpleString(m_scriptText.Ptr());
+ PyErr_Print();
+
+ /* Added in 2.48a, the last_traceback can reference Objects for example, increasing
+ * their user count. Not to mention holding references to wrapped data.
+ * This is especially bad when the PyObject for the wrapped data is free'd, after blender
+ * has alredy dealocated the pointer */
+ PySys_SetObject( (char *)"last_traceback", Py_None);
+ PyErr_Clear(); /* just to be sure */
+
+ return false;
+ }
+}
void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
{
@@ -249,33 +312,13 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
if (m_bModified)
{
- // if a script already exists, decref it before replace the pointer to a new script
- if (m_bytecode)
- {
- Py_DECREF(m_bytecode);
- m_bytecode=NULL;
- }
- // recompile the scripttext into bytecode
- m_bytecode = Py_CompileString(m_scriptText.Ptr(), m_scriptName.Ptr(), Py_file_input);
- if (!m_bytecode)
- {
- // didn't compile, so instead of compile, complain
- // something is wrong, tell the user what went wrong
- printf("Python compile error from controller \"%s\": \n", GetName().Ptr());
- //PyRun_SimpleString(m_scriptText.Ptr());
- PyErr_Print();
-
- /* Added in 2.48a, the last_traceback can reference Objects for example, increasing
- * their user count. Not to mention holding references to wrapped data.
- * This is especially bad when the PyObject for the wrapped data is free'd, after blender
- * has alredy dealocated the pointer */
- PySys_SetObject( "last_traceback", Py_None);
- PyErr_Clear(); /* just to be sure */
-
+ if (Compile()==false) // sets m_bModified to false
return;
- }
- m_bModified=false;
}
+ if (!m_bytecode) {
+ return;
+ }
+
/*
* This part here with excdict is a temporary patch
@@ -313,7 +356,7 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
* their user count. Not to mention holding references to wrapped data.
* This is especially bad when the PyObject for the wrapped data is free'd, after blender
* has alredy dealocated the pointer */
- PySys_SetObject( "last_traceback", Py_None);
+ PySys_SetObject( (char *)"last_traceback", Py_None);
PyErr_Clear(); /* just to be sure */
//PyRun_SimpleString(m_scriptText.Ptr());
@@ -329,30 +372,63 @@ void SCA_PythonController::Trigger(SCA_LogicManager* logicmgr)
-PyObject* SCA_PythonController::_getattr(const STR_String& attr)
+PyObject* SCA_PythonController::_getattr(const char *attr)
{
- if (attr == "script") {
- return PyString_FromString(m_scriptText);
- }
- if (attr == "state") {
+ if (!strcmp(attr,"state")) {
return PyInt_FromLong(m_statemask);
}
+ if (!strcmp(attr,"script")) {
+ return PyString_FromString(m_scriptText);
+ }
_getattr_up(SCA_IController);
}
-int SCA_PythonController::_setattr(const STR_String& attr, PyObject *value)
+int SCA_PythonController::_setattr(const char *attr, PyObject *value)
{
- if (attr == "script") {
- PyErr_SetString(PyExc_AttributeError, "script is read only, use setScript() to update the script");
+ if (!strcmp(attr,"state")) {
+ PyErr_SetString(PyExc_AttributeError, "state is read only");
return 1;
}
- if (attr == "state") {
- PyErr_SetString(PyExc_AttributeError, "state is read only");
+ if (!strcmp(attr,"script")) {
+ char *scriptArg = PyString_AsString(value);
+
+ if (scriptArg==NULL) {
+ PyErr_SetString(PyExc_TypeError, "expected a string (script name)");
+ return -1;
+ }
+
+ /* set scripttext sets m_bModified to true,
+ so next time the script is needed, a reparse into byte code is done */
+ this->SetScriptText(scriptArg);
+
return 1;
}
return SCA_IController::_setattr(attr, value);
}
+PyObject* SCA_PythonController::PyActivate(PyObject* self, PyObject *value)
+{
+ SCA_IActuator* actu = LinkedActuatorFromPy(value);
+ if(actu==NULL)
+ return NULL;
+
+ CValue* boolval = new CBoolValue(true);
+ m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, boolval);
+ boolval->Release();
+ Py_RETURN_NONE;
+}
+
+PyObject* SCA_PythonController::PyDeActivate(PyObject* self, PyObject *value)
+{
+ SCA_IActuator* actu = LinkedActuatorFromPy(value);
+ if(actu==NULL)
+ return NULL;
+
+ CValue* boolval = new CBoolValue(false);
+ m_sCurrentLogicManager->AddActiveActuator((SCA_IActuator*)actu, boolval);
+ boolval->Release();
+ Py_RETURN_NONE;
+}
PyObject* SCA_PythonController::PyGetActuators(PyObject* self)
{
@@ -410,8 +486,7 @@ SCA_PythonController::PyGetActuator(PyObject* self, PyObject* value)
for (unsigned int index=0;index<m_linkedactuators.size();index++)
{
SCA_IActuator* actua = m_linkedactuators[index];
- STR_String realname = actua->GetName();
- if (realname == scriptArg)
+ if (actua->GetName() == scriptArg)
{
return actua->AddRef();
}
@@ -448,6 +523,9 @@ PyObject* SCA_PythonController::PyGetScript(PyObject* self)
PyObject* SCA_PythonController::PySetScript(PyObject* self, PyObject* value)
{
char *scriptArg = PyString_AsString(value);
+
+ ShowDeprecationWarning("setScript()", "the script property");
+
if (scriptArg==NULL) {
PyErr_SetString(PyExc_TypeError, "expected a string (script name)");
return NULL;
diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h
index 1918cc488d8..4ec18f32c23 100644
--- a/source/gameengine/GameLogic/SCA_PythonController.h
+++ b/source/gameengine/GameLogic/SCA_PythonController.h
@@ -70,15 +70,20 @@ class SCA_PythonController : public SCA_IController
void AddTriggeredSensor(class SCA_ISensor* sensor)
{ m_triggeredSensors.push_back(sensor); }
int IsTriggered(class SCA_ISensor* sensor);
+ bool Compile();
static const char* sPyGetCurrentController__doc__;
static PyObject* sPyGetCurrentController(PyObject* self);
static const char* sPyAddActiveActuator__doc__;
static PyObject* sPyAddActiveActuator(PyObject* self,
PyObject* args);
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value);
+ static SCA_IActuator* LinkedActuatorFromPy(PyObject *value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
+
+ KX_PYMETHOD_O(SCA_PythonController,Activate);
+ KX_PYMETHOD_O(SCA_PythonController,DeActivate);
KX_PYMETHOD_DOC_NOARGS(SCA_PythonController,GetSensors);
KX_PYMETHOD_DOC_NOARGS(SCA_PythonController,GetActuators);
KX_PYMETHOD_DOC_O(SCA_PythonController,GetSensor);
diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
index 840b95d559a..d6c73f21f37 100644
--- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp
@@ -369,22 +369,22 @@ PyAttributeDef SCA_RandomActuator::Attributes[] = {
{ NULL } //Sentinel
};
-PyObject* SCA_RandomActuator::_getattr(const STR_String& attr) {
+PyObject* SCA_RandomActuator::_getattr(const char *attr) {
PyObject* object = _getattr_self(Attributes, this, attr);
if (object != NULL)
return object;
- if (attr == "seed") {
+ if (!strcmp(attr, "seed")) {
return PyInt_FromLong(m_base->GetSeed());
}
_getattr_up(SCA_IActuator);
}
-int SCA_RandomActuator::_setattr(const STR_String& attr, PyObject *value)
+int SCA_RandomActuator::_setattr(const char *attr, PyObject *value)
{
int ret = _setattr_self(Attributes, this, attr, value);
if (ret >= 0)
return ret;
- if (attr == "seed") {
+ if (!strcmp(attr, "seed")) {
if (PyInt_Check(value)) {
int ival = PyInt_AsLong(value);
m_base->SetSeed(ival);
@@ -413,7 +413,7 @@ PyObject* SCA_RandomActuator::PySetSeed(PyObject* self, PyObject* args, PyObject
m_base->SetSeed(seedArg);
- Py_Return;
+ Py_RETURN_NONE;
}
/* 2. getSeed */
const char SCA_RandomActuator::GetSeed_doc[] =
@@ -478,7 +478,7 @@ PyObject* SCA_RandomActuator::PySetProperty(PyObject* self, PyObject* args, PyOb
}
prop->Release();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 10. getProperty */
const char SCA_RandomActuator::GetProperty_doc[] =
@@ -506,7 +506,7 @@ PyObject* SCA_RandomActuator::PySetBoolConst(PyObject* self,
m_distribution = KX_RANDOMACT_BOOL_CONST;
m_parameter1 = (paraArg) ? 1.0 : 0.0;
- Py_Return;
+ Py_RETURN_NONE;
}
/* 12. setBoolUniform, */
const char SCA_RandomActuator::SetBoolUniform_doc[] =
@@ -518,7 +518,7 @@ PyObject* SCA_RandomActuator::PySetBoolUniform(PyObject* self,
/* no args */
m_distribution = KX_RANDOMACT_BOOL_UNIFORM;
enforceConstraints();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 13. setBoolBernouilli, */
const char SCA_RandomActuator::SetBoolBernouilli_doc[] =
@@ -536,7 +536,7 @@ PyObject* SCA_RandomActuator::PySetBoolBernouilli(PyObject* self,
m_distribution = KX_RANDOMACT_BOOL_BERNOUILLI;
m_parameter1 = paraArg;
enforceConstraints();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 14. setIntConst,*/
const char SCA_RandomActuator::SetIntConst_doc[] =
@@ -554,7 +554,7 @@ PyObject* SCA_RandomActuator::PySetIntConst(PyObject* self,
m_distribution = KX_RANDOMACT_INT_CONST;
m_parameter1 = paraArg;
enforceConstraints();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 15. setIntUniform,*/
const char SCA_RandomActuator::SetIntUniform_doc[] =
@@ -575,7 +575,7 @@ PyObject* SCA_RandomActuator::PySetIntUniform(PyObject* self,
m_parameter1 = paraArg1;
m_parameter2 = paraArg2;
enforceConstraints();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 16. setIntPoisson, */
const char SCA_RandomActuator::SetIntPoisson_doc[] =
@@ -595,7 +595,7 @@ PyObject* SCA_RandomActuator::PySetIntPoisson(PyObject* self,
m_distribution = KX_RANDOMACT_INT_POISSON;
m_parameter1 = paraArg;
enforceConstraints();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 17. setFloatConst,*/
const char SCA_RandomActuator::SetFloatConst_doc[] =
@@ -613,7 +613,7 @@ PyObject* SCA_RandomActuator::PySetFloatConst(PyObject* self,
m_distribution = KX_RANDOMACT_FLOAT_CONST;
m_parameter1 = paraArg;
enforceConstraints();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 18. setFloatUniform, */
const char SCA_RandomActuator::SetFloatUniform_doc[] =
@@ -634,7 +634,7 @@ PyObject* SCA_RandomActuator::PySetFloatUniform(PyObject* self,
m_parameter1 = paraArg1;
m_parameter2 = paraArg2;
enforceConstraints();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 19. setFloatNormal, */
const char SCA_RandomActuator::SetFloatNormal_doc[] =
@@ -655,7 +655,7 @@ PyObject* SCA_RandomActuator::PySetFloatNormal(PyObject* self,
m_parameter1 = paraArg1;
m_parameter2 = paraArg2;
enforceConstraints();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 20. setFloatNegativeExponential, */
const char SCA_RandomActuator::SetFloatNegativeExponential_doc[] =
@@ -674,7 +674,7 @@ PyObject* SCA_RandomActuator::PySetFloatNegativeExponential(PyObject* self,
m_distribution = KX_RANDOMACT_FLOAT_NEGATIVE_EXPONENTIAL;
m_parameter1 = paraArg;
enforceConstraints();
- Py_Return;
+ Py_RETURN_NONE;
}
/* eof */
diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.h b/source/gameengine/GameLogic/SCA_RandomActuator.h
index de8faaf9c72..0d404fa8a9f 100644
--- a/source/gameengine/GameLogic/SCA_RandomActuator.h
+++ b/source/gameengine/GameLogic/SCA_RandomActuator.h
@@ -96,8 +96,8 @@ class SCA_RandomActuator : public SCA_IActuator
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
/* 1. setSeed */
KX_PYMETHOD_DOC(SCA_RandomActuator,SetSeed);
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
index 8fae0bbeaba..5354c120f52 100644
--- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
@@ -165,22 +165,22 @@ PyAttributeDef SCA_RandomSensor::Attributes[] = {
{NULL} //Sentinel
};
-PyObject* SCA_RandomSensor::_getattr(const STR_String& attr) {
+PyObject* SCA_RandomSensor::_getattr(const char *attr) {
PyObject* object = _getattr_self(Attributes, this, attr);
if (object != NULL)
return object;
- if (attr == "seed") {
+ if (!strcmp(attr,"seed")) {
return PyInt_FromLong(m_basegenerator->GetSeed());
}
_getattr_up(SCA_ISensor);
}
-int SCA_RandomSensor::_setattr(const STR_String& attr, PyObject *value)
+int SCA_RandomSensor::_setattr(const char *attr, PyObject *value)
{
int ret = _setattr_self(Attributes, this, attr, value);
if (ret >= 0)
return ret;
- if (attr == "seed") {
+ if (!strcmp(attr,"seed")) {
if (PyInt_Check(value)) {
int ival = PyInt_AsLong(value);
m_basegenerator->SetSeed(ival);
@@ -209,7 +209,7 @@ PyObject* SCA_RandomSensor::PySetSeed(PyObject* self, PyObject* args, PyObject*
m_basegenerator->SetSeed(seedArg);
- Py_Return;
+ Py_RETURN_NONE;
}
/* 2. getSeed */
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h
index 009efc32aac..d808db07536 100644
--- a/source/gameengine/GameLogic/SCA_RandomSensor.h
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.h
@@ -60,8 +60,8 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
/* 1. setSeed */
KX_PYMETHOD_DOC(SCA_RandomSensor,SetSeed);
diff --git a/source/gameengine/GameLogic/SCA_XNORController.cpp b/source/gameengine/GameLogic/SCA_XNORController.cpp
index 3ef7c07fe0a..b2734dd1b33 100644
--- a/source/gameengine/GameLogic/SCA_XNORController.cpp
+++ b/source/gameengine/GameLogic/SCA_XNORController.cpp
@@ -141,7 +141,11 @@ PyMethodDef SCA_XNORController::Methods[] = {
{NULL,NULL} //Sentinel
};
-PyObject* SCA_XNORController::_getattr(const STR_String& attr) {
+PyAttributeDef SCA_XNORController::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* SCA_XNORController::_getattr(const char *attr) {
_getattr_up(SCA_IController);
}
diff --git a/source/gameengine/GameLogic/SCA_XNORController.h b/source/gameengine/GameLogic/SCA_XNORController.h
index 4b1eaee95d8..a431a72c177 100644
--- a/source/gameengine/GameLogic/SCA_XNORController.h
+++ b/source/gameengine/GameLogic/SCA_XNORController.h
@@ -48,7 +48,7 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
};
diff --git a/source/gameengine/GameLogic/SCA_XORController.cpp b/source/gameengine/GameLogic/SCA_XORController.cpp
index 6499c62f5f2..662ef523d56 100644
--- a/source/gameengine/GameLogic/SCA_XORController.cpp
+++ b/source/gameengine/GameLogic/SCA_XORController.cpp
@@ -141,7 +141,11 @@ PyMethodDef SCA_XORController::Methods[] = {
{NULL,NULL} //Sentinel
};
-PyObject* SCA_XORController::_getattr(const STR_String& attr) {
+PyAttributeDef SCA_XORController::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* SCA_XORController::_getattr(const char *attr) {
_getattr_up(SCA_IController);
}
diff --git a/source/gameengine/GameLogic/SCA_XORController.h b/source/gameengine/GameLogic/SCA_XORController.h
index f50cd33c125..2fbc7866ecf 100644
--- a/source/gameengine/GameLogic/SCA_XORController.h
+++ b/source/gameengine/GameLogic/SCA_XORController.h
@@ -48,7 +48,7 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
};
diff --git a/source/gameengine/GameLogic/SConscript b/source/gameengine/GameLogic/SConscript
index 25cf73cd079..88e5f7e87cc 100644
--- a/source/gameengine/GameLogic/SConscript
+++ b/source/gameengine/GameLogic/SConscript
@@ -17,4 +17,9 @@ if env['WITH_BF_SDL']:
else:
defs += ' DISABLE_SDL'
-env.BlenderLib ( 'bf_logic', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[315, 100] )
+cxxflags = []
+if env['OURPLATFORM']=='win32-vc':
+ cxxflags.append ('/GR')
+ cxxflags.append ('/O2')
+
+env.BlenderLib ( 'bf_logic', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[330, 100], cxx_compileflags=cxxflags )
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
index 78d8eaf2aa3..c0d6248a3ca 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
@@ -85,7 +85,7 @@ void GPC_RenderTools::EndFrame(RAS_IRasterizer* rasty)
* has a maximum of 8 lights (simultaneous), so 20 * 8 lights are possible in
* a scene. */
-void GPC_RenderTools::ProcessLighting(int layer, const MT_Transform& viewmat)
+void GPC_RenderTools::ProcessLighting(RAS_IRasterizer *rasty, int layer, const MT_Transform& viewmat)
{
if(m_lastlightlayer == layer)
return;
@@ -106,12 +106,12 @@ void GPC_RenderTools::ProcessLighting(int layer, const MT_Transform& viewmat)
}
if(enable)
- EnableOpenGLLights();
+ EnableOpenGLLights(rasty);
else
DisableOpenGLLights();
}
-void GPC_RenderTools::EnableOpenGLLights()
+void GPC_RenderTools::EnableOpenGLLights(RAS_IRasterizer *rasty)
{
if(m_lastlighting == true)
return;
@@ -120,7 +120,8 @@ void GPC_RenderTools::EnableOpenGLLights()
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, true);
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+ glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (rasty->GetCameraOrtho())? GL_FALSE: GL_TRUE);
if (GLEW_EXT_separate_specular_color || GLEW_VERSION_1_2)
glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
diff --git a/source/gameengine/GamePlayer/common/GPC_RenderTools.h b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
index 382956e73ea..2a1b66a3aa9 100644
--- a/source/gameengine/GamePlayer/common/GPC_RenderTools.h
+++ b/source/gameengine/GamePlayer/common/GPC_RenderTools.h
@@ -65,9 +65,9 @@ public:
void EndFrame(RAS_IRasterizer* rasty);
void BeginFrame(RAS_IRasterizer* rasty);
- void EnableOpenGLLights();
+ void EnableOpenGLLights(RAS_IRasterizer *rasty);
void DisableOpenGLLights();
- void ProcessLighting(int layer, const MT_Transform& viewmat);
+ void ProcessLighting(RAS_IRasterizer *rasty, int layer, const MT_Transform& viewmat);
/* @attention mode is ignored here */
void RenderText2D(RAS_TEXT_RENDER_MODE mode,
diff --git a/source/gameengine/GamePlayer/common/SConscript b/source/gameengine/GamePlayer/common/SConscript
index 30f20a670d3..23ad413350b 100644
--- a/source/gameengine/GamePlayer/common/SConscript
+++ b/source/gameengine/GamePlayer/common/SConscript
@@ -39,15 +39,13 @@ incs = ['.',
'#source/gameengine/Network',
'#source/gameengine/SceneGraph',
'#source/gameengine/Physics/common',
- '#source/gameengine/Physics/Sumo',
- '#source/gameengine/Physics/Sumo/Fuzzics/include',
'#source/gameengine/Network/LoopBackNetwork',
'#source/gameengine/GamePlayer/ghost',
'#source/blender/misc',
'#source/blender/blenloader',
'#source/blender/gpu',
'#extern/glew/include']
-
+
#This is all plugin stuff!
#if sys.platform=='win32':
# source_files += ['windows/GPW_Canvas.cpp',
@@ -62,13 +60,18 @@ incs = ['.',
# 'unix/GPU_System.cpp']
# gp_common_env.Append ( CPPPATH = ['unix'])
+if env['WITH_BF_SOLID']:
+ incs.append('#source/gameengine/Physics/Sumo')
+ incs.append('#source/gameengine/Physics/Sumo/Fuzzics/include')
+ incs += Split(env['BF_SOLID_INC'])
+
incs += Split(env['BF_PYTHON_INC'])
-incs += Split(env['BF_SOLID_INC'])
incs += Split(env['BF_PNG_INC'])
incs += Split(env['BF_ZLIB_INC'])
-cflags=[]
+cxxflags = []
if env['OURPLATFORM']=='win32-vc':
- cflags = ['/GR']
+ cxxflags.append ('/GR')
+ cxxflags.append ('/O2')
-env.BlenderLib (libname='gp_common', sources=source_files, includes=incs, defines = [], libtype='player', priority=5, compileflags=cflags)
+env.BlenderLib (libname='gp_common', sources=source_files, includes=incs, defines = [], libtype='player', priority=5, cxx_compileflags=cxxflags)
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index c09772c6196..d993694ab4a 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -163,33 +163,39 @@ void usage(const char* program)
consoleoption = "";
#endif
- printf("usage: %s [-w l t w h] %s[-g gamengineoptions] "
+ printf("usage: %s [-w [w h l t]] [-f [fw fh fb ff]] %s[-g gamengineoptions] "
"[-s stereomode] filename.blend\n", program, consoleoption);
- printf(" -h: Prints this command summary\n");
+ printf(" -h: Prints this command summary\n\n");
printf(" -w: display in a window\n");
+ printf(" --Optional parameters--\n");
+ printf(" w = window width\n");
+ printf(" h = window height\n\n");
printf(" l = window left coordinate\n");
printf(" t = window top coordinate\n");
- printf(" w = window width\n");
- printf(" h = window height\n");
+ printf(" Note: If w or h is defined, both must be defined.\n");
+ printf(" Also, if l or t is defined, all options must be used.\n\n");
printf(" -f: start game in full screen mode\n");
+ printf(" --Optional parameters--\n");
printf(" fw = full screen mode pixel width\n");
- printf(" fh = full screen mode pixel height\n");
+ printf(" fh = full screen mode pixel height\n\n");
printf(" fb = full screen mode bits per pixel\n");
printf(" ff = full screen mode frequency\n");
+ printf(" Note: If fw or fh is defined, both must be defined.\n");
+ printf(" Also, if fb is used, fw and fh must be used. ff requires all options.\n\n");
printf(" -s: start player in stereo\n");
printf(" stereomode: hwpageflip (Quad buffered shutter glasses)\n");
printf(" syncdoubling (Above Below)\n");
printf(" sidebyside (Left Right)\n");
printf(" anaglyph (Red-Blue glasses)\n");
printf(" vinterlace (Vertical interlace for autostereo display)\n");
- printf(" depending on the type of stereo you want\n");
+ printf(" depending on the type of stereo you want\n\n");
#ifndef _WIN32
- printf(" -i: parent windows ID \n");
+ printf(" -i: parent windows ID \n\n");
#endif
#ifdef _WIN32
- printf(" -c: keep console window open\n");
+ printf(" -c: keep console window open\n\n");
#endif
- printf(" -d: turn debugging on\n");
+ printf(" -d: turn debugging on\n\n");
printf(" -g: game engine options:\n\n");
printf(" Name Default Description\n");
printf(" ------------------------------------------------------------------------\n");
@@ -201,7 +207,7 @@ void usage(const char* program)
printf(" blender_material 0 Enable material settings\n");
printf(" ignore_deprecation_warnings 0 Ignore deprecation warnings\n");
printf("\n");
- printf("example: %s -w 10 10 320 200 -g noaudio c:\\loadtest.blend\n", program);
+ printf("example: %s -w 320 200 10 10 -g noaudio c:\\loadtest.blend\n", program);
printf("example: %s -g show_framerate = 0 c:\\loadtest.blend\n", program);
}
@@ -241,7 +247,7 @@ static void get_filename(int argc, char **argv, char *filename)
if (BLI_exists(gamefile))
BLI_strncpy(filename, gamefile, FILE_MAXDIR + FILE_MAXFILE);
- delete gamefile;
+ delete [] gamefile;
}
#else
@@ -430,54 +436,41 @@ int main(int argc, char** argv)
G.f |= G_DEBUG; /* std output printf's */
MEM_set_memory_debug();
break;
-
- case 'p':
- // Parse window position and size options
- if (argv[i][2] == 0) {
- i++;
- if ((i + 4) < argc)
- {
- windowLeft = atoi(argv[i++]);
- windowTop = atoi(argv[i++]);
- windowWidth = atoi(argv[i++]);
- windowHeight = atoi(argv[i++]);
- windowParFound = true;
- }
- else
- {
- error = true;
- printf("error: too few options for window argument.\n");
- }
- } else { /* mac specific */
-
- if (strncmp(argv[i], "-psn_", 5)==0)
- i++; /* skip process serial number */
- }
- break;
+
case 'f':
i++;
fullScreen = true;
fullScreenParFound = true;
- if ((i + 2) < argc && argv[i][0] != '-' && argv[i+1][0] != '-')
+ if ((i + 2) <= argc && argv[i][0] != '-' && argv[i+1][0] != '-')
{
fullScreenWidth = atoi(argv[i++]);
fullScreenHeight = atoi(argv[i++]);
- if ((i + 1) < argc && argv[i][0] != '-')
+ if ((i + 1) <= argc && argv[i][0] != '-')
{
fullScreenBpp = atoi(argv[i++]);
- if ((i + 1) < argc && argv[i][0] != '-')
+ if ((i + 1) <= argc && argv[i][0] != '-')
fullScreenFrequency = atoi(argv[i++]);
}
}
break;
case 'w':
// Parse window position and size options
+ i++;
+ fullScreen = false;
+ windowParFound = true;
+
+ if ((i + 2) <= argc && argv[i][0] != '-' && argv[i+1][0] != '-')
{
- fullScreen = false;
- fullScreenParFound = true;
- i++;
+ windowWidth = atoi(argv[i++]);
+ windowHeight = atoi(argv[i++]);
+ if ((i +2) <= argc && argv[i][0] != '-' && argv[i+1][0] != '-')
+ {
+ windowLeft = atoi(argv[i++]);
+ windowTop = atoi(argv[i++]);
+ }
}
break;
+
case 'h':
usage(argv[0]);
return 0;
diff --git a/source/gameengine/GamePlayer/ghost/SConscript b/source/gameengine/GamePlayer/ghost/SConscript
index 7ad2fdd37a7..9b17ed3757b 100644
--- a/source/gameengine/GamePlayer/ghost/SConscript
+++ b/source/gameengine/GamePlayer/ghost/SConscript
@@ -34,8 +34,6 @@ incs = ['.',
'#source/gameengine/Network',
'#source/gameengine/SceneGraph',
'#source/gameengine/Physics/common',
- '#source/gameengine/Physics/Sumo',
- '#source/gameengine/Physics/Sumo/Fuzzics/include',
'#source/gameengine/Network/LoopBackNetwork',
'#source/gameengine/GamePlayer/common',
'#source/blender/misc',
@@ -43,14 +41,19 @@ incs = ['.',
'#source/blender/gpu',
'#extern/glew/include']
+if env['WITH_BF_SOLID']:
+ incs.append(['#source/gameengine/Physics/Sumo', '#source/gameengine/Physics/Sumo/Fuzzics/include'])
+ incs += Split(env['BF_SOLID_INC'])
+
incs += Split(env['BF_PYTHON_INC'])
-incs += Split(env['BF_SOLID_INC'])
-cflags = []
+
+cxxflags = []
if env['OURPLATFORM']=='win32-vc':
- cflags = ['/GR']
+ cxxflags.append ('/GR')
+ cxxflags.append ('/O2')
defs = ''
if env['WITH_BF_FFMPEG']:
defs += ' WITH_FFMPEG'
-env.BlenderLib (libname='gp_ghost', sources=source_files, includes = incs, defines = Split(defs), libtype='player',priority=5, compileflags=cflags)
+env.BlenderLib (libname='gp_ghost', sources=source_files, includes = incs, defines = Split(defs), libtype='player',priority=5, cxx_compileflags=cxxflags)
diff --git a/source/gameengine/Ketsji/BL_Shader.cpp b/source/gameengine/Ketsji/BL_Shader.cpp
index 80892764089..60cb288436a 100644
--- a/source/gameengine/Ketsji/BL_Shader.cpp
+++ b/source/gameengine/Ketsji/BL_Shader.cpp
@@ -18,7 +18,7 @@
#define spit(x) std::cout << x << std::endl;
#define SORT_UNIFORMS 1
-#define UNIFORM_MAX_LEN sizeof(float)*16
+#define UNIFORM_MAX_LEN (int)sizeof(float)*16
#define MAX_LOG_LEN 262144 // bounds
BL_Uniform::BL_Uniform(int data_size)
@@ -108,7 +108,7 @@ void BL_Uniform::SetData(int location, int type,bool transpose)
#endif
}
-const bool BL_Shader::Ok()const
+bool BL_Shader::Ok()const
{
return (mShader !=0 && mOk && mUse);
}
@@ -729,7 +729,7 @@ void BL_Shader::SetUniform(int uniform, const int* val, int len)
}
-PyObject* BL_Shader::_getattr(const STR_String& attr)
+PyObject* BL_Shader::_getattr(const char *attr)
{
_getattr_up(PyObjectPlus);
}
@@ -767,6 +767,9 @@ PyMethodDef BL_Shader::Methods[] =
{NULL,NULL} //Sentinel
};
+PyAttributeDef BL_Shader::Attributes[] = {
+ { NULL } //Sentinel
+};
PyTypeObject BL_Shader::Type = {
PyObject_HEAD_INIT(&PyType_Type)
@@ -796,7 +799,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProg
if(mShader !=0 && mOk )
{
// already set...
- Py_Return;
+ Py_RETURN_NONE;
}
char *v,*f;
int apply=0;
@@ -807,12 +810,12 @@ KX_PYMETHODDEF_DOC( BL_Shader, setSource," setSource(vertexProgram, fragmentProg
if( LinkProgram() ) {
glUseProgramObjectARB( mShader );
mUse = apply!=0;
- Py_Return;
+ Py_RETURN_NONE;
}
vertProg = 0;
fragProg = 0;
mUse = 0;
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
}
@@ -827,7 +830,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, delSource, "delSource( )" )
mShader = 0;
mOk = 0;
mUse = 0;
- Py_Return;
+ Py_RETURN_NONE;
}
KX_PYMETHODDEF_DOC( BL_Shader, isValid, "isValid()" )
@@ -871,7 +874,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, validate, "validate()")
MEM_freeN(logInf);
logInf=0;
}
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -912,7 +915,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setNumberOfPasses, "setNumberOfPasses( max-pass )
return NULL;
mPass = 1;
- Py_Return;
+ Py_RETURN_NONE;
}
/// access functions
@@ -935,7 +938,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform1f, "setUniform1f(name, fx)" )
SetUniform( loc, (float)value );
#endif
}
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
}
@@ -959,7 +962,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform2f , "setUniform2f(name, fx, fy)")
SetUniform(loc, array, 2);
#endif
}
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
}
@@ -983,7 +986,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform3f, "setUniform3f(name, fx,fy,fz) ")
SetUniform(loc, array, 3);
#endif
}
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
@@ -1008,7 +1011,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform4f, "setUniform4f(name, fx,fy,fz, fw) "
SetUniform(loc, array, 4);
#endif
}
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
}
@@ -1032,7 +1035,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform1i, "setUniform1i(name, ix)" )
SetUniform(loc, (int)value);
#endif
}
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
}
@@ -1056,7 +1059,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform2i , "setUniform2i(name, ix, iy)")
SetUniform(loc, array, 2);
#endif
}
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
}
@@ -1081,7 +1084,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform3i, "setUniform3i(name, ix,iy,iz) ")
SetUniform(loc, array, 3);
#endif
}
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
}
@@ -1104,7 +1107,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniform4i, "setUniform4i(name, ix,iy,iz, iw) "
SetUniform(loc, array, 4);
#endif
}
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
}
@@ -1144,7 +1147,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or lis
#else
SetUniform(loc, array2, 2);
#endif
- Py_Return;
+ Py_RETURN_NONE;
} break;
case 3:
{
@@ -1154,7 +1157,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or lis
#else
SetUniform(loc, array3, 3);
#endif
- Py_Return;
+ Py_RETURN_NONE;
}break;
case 4:
{
@@ -1164,7 +1167,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformfv , "setUniformfv( float (list2 or lis
#else
SetUniform(loc, array4, 4);
#endif
- Py_Return;
+ Py_RETURN_NONE;
}break;
default:
{
@@ -1212,7 +1215,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3
#else
SetUniform(loc, array2, 2);
#endif
- Py_Return;
+ Py_RETURN_NONE;
} break;
case 3:
{
@@ -1223,7 +1226,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3
#else
SetUniform(loc, array3, 3);
#endif
- Py_Return;
+ Py_RETURN_NONE;
}break;
case 4:
{
@@ -1234,7 +1237,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformiv, "setUniformiv( int (list2 or list3
#else
SetUniform(loc, array4, 4);
#endif
- Py_Return;
+ Py_RETURN_NONE;
}break;
default:
{
@@ -1282,7 +1285,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix4,
#else
SetUniform(loc,mat,(transp!=0));
#endif
- Py_Return;
+ Py_RETURN_NONE;
}
}
}
@@ -1323,7 +1326,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformMatrix3,
#else
SetUniform(loc,mat,(transp!=0));
#endif
- Py_Return;
+ Py_RETURN_NONE;
}
}
@@ -1346,7 +1349,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setAttrib, "setAttrib(enum)" )
mAttr=SHD_TANGENT;
glUseProgramObjectARB(mShader);
glBindAttribLocationARB(mShader, mAttr, "Tangent");
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
}
@@ -1376,7 +1379,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformDef, "setUniformDef(name, enum)" )
}
if(defined)
{
- Py_Return;
+ Py_RETURN_NONE;
}
BL_DefUniform *uni = new BL_DefUniform();
@@ -1384,7 +1387,7 @@ KX_PYMETHODDEF_DOC( BL_Shader, setUniformDef, "setUniformDef(name, enum)" )
uni->mType = nloc;
uni->mFlag = 0;
mPreDef.push_back(uni);
- Py_Return;
+ Py_RETURN_NONE;
}
}
return NULL;
diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h
index 18ca8f8b4f8..76acd5513ef 100644
--- a/source/gameengine/Ketsji/BL_Shader.h
+++ b/source/gameengine/Ketsji/BL_Shader.h
@@ -166,7 +166,7 @@ public:
//const BL_Sampler* GetSampler(int i);
void SetSampler(int loc, int unit);
- const bool Ok()const;
+ bool Ok()const;
unsigned int GetProg();
void SetProg(bool enable);
int GetAttribute(){return mAttr;};
@@ -202,7 +202,7 @@ public:
void SetUniform(int uniform, const int val);
// Python interface
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
// -----------------------------------
KX_PYMETHOD_DOC( BL_Shader, setSource );
diff --git a/source/gameengine/Ketsji/BL_Texture.cpp b/source/gameengine/Ketsji/BL_Texture.cpp
index f0ef84032f7..5d40ba7d75c 100644
--- a/source/gameengine/Ketsji/BL_Texture.cpp
+++ b/source/gameengine/Ketsji/BL_Texture.cpp
@@ -609,7 +609,7 @@ int BL_Texture::GetPow2(int n)
void BL_Texture::SplitEnvMap(EnvMap *map)
{
- if (!map || !map->ima || map->ima && !map->ima->ok) return;
+ if (!map || !map->ima || (map->ima && !map->ima->ok)) return;
ImBuf *ibuf= BKE_image_get_ibuf(map->ima, NULL);
if (ibuf)
my_envmap_split_ima(map, ibuf);
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
index 85921ae75ca..4e5f27df2da 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.cpp
@@ -143,7 +143,11 @@ PyMethodDef KX_NetworkMessageActuator::Methods[] = {
{NULL,NULL} // Sentinel
};
-PyObject* KX_NetworkMessageActuator::_getattr(const STR_String& attr) {
+PyAttributeDef KX_NetworkMessageActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* KX_NetworkMessageActuator::_getattr(const char *attr) {
_getattr_up(SCA_IActuator);
}
@@ -162,7 +166,7 @@ PyObject* KX_NetworkMessageActuator::PySetToPropName(
return NULL;
}
- Py_Return;
+ Py_RETURN_NONE;
}
// 2. SetSubject
@@ -180,7 +184,7 @@ PyObject* KX_NetworkMessageActuator::PySetSubject(
return NULL;
}
- Py_Return;
+ Py_RETURN_NONE;
}
// 3. SetBodyType
@@ -198,7 +202,7 @@ PyObject* KX_NetworkMessageActuator::PySetBodyType(
return NULL;
}
- Py_Return;
+ Py_RETURN_NONE;
}
// 4. SetBody
@@ -216,6 +220,6 @@ PyObject* KX_NetworkMessageActuator::PySetBody(
return NULL;
}
- Py_Return;
+ Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
index 653107699c7..96b55ef839b 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
@@ -61,7 +61,7 @@ public:
/* Python interface ------------------------------------------- */
/* ------------------------------------------------------------ */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
KX_PYMETHOD(KX_NetworkMessageActuator, SetToPropName);
KX_PYMETHOD(KX_NetworkMessageActuator, SetSubject);
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
index 8956df9c96b..ac89d8b0716 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
@@ -213,7 +213,11 @@ PyMethodDef KX_NetworkMessageSensor::Methods[] = {
{NULL,NULL} //Sentinel
};
-PyObject* KX_NetworkMessageSensor::_getattr(const STR_String& attr) {
+PyAttributeDef KX_NetworkMessageSensor::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* KX_NetworkMessageSensor::_getattr(const char *attr) {
_getattr_up(SCA_ISensor); // implicit return!
}
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
index 8cdfd6cdb5a..26adbc9945a 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
@@ -72,7 +72,7 @@ public:
/* Python interface -------------------------------------------- */
/* ------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
KX_PYMETHOD_DOC_O(KX_NetworkMessageSensor, SetSubjectFilterText);
KX_PYMETHOD_DOC_NOARGS(KX_NetworkMessageSensor, GetFrameMessageCount);
diff --git a/source/gameengine/Ketsji/KXNetwork/SConscript b/source/gameengine/Ketsji/KXNetwork/SConscript
index 93b65757ac5..b417edf6413 100644
--- a/source/gameengine/Ketsji/KXNetwork/SConscript
+++ b/source/gameengine/Ketsji/KXNetwork/SConscript
@@ -9,4 +9,10 @@ incs += ' #source/gameengine/Network'
incs += ' ' + env['BF_PYTHON_INC']
-env.BlenderLib ( 'kx_network', Split(sources), Split(incs), defines=[],libtype=['core', 'player'], priority=[400, 145] )
+cxxflags = []
+if env['OURPLATFORM']=='win32-vc':
+ cxxflags.append ('/GR')
+ cxxflags.append ('/O2')
+
+
+env.BlenderLib ( 'kx_network', Split(sources), Split(incs), defines=[],libtype=['core', 'player'], priority=[400, 145], cxx_compileflags=cxxflags )
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
index f92200780d5..b9bd7647f89 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp
@@ -748,6 +748,9 @@ PyMethodDef KX_BlenderMaterial::Methods[] =
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_BlenderMaterial::Attributes[] = {
+ { NULL } //Sentinel
+};
PyTypeObject KX_BlenderMaterial::Type = {
PyObject_HEAD_INIT(&PyType_Type)
@@ -772,12 +775,12 @@ PyParentObject KX_BlenderMaterial::Parents[] = {
};
-PyObject* KX_BlenderMaterial::_getattr(const STR_String& attr)
+PyObject* KX_BlenderMaterial::_getattr(const char *attr)
{
_getattr_up(PyObjectPlus);
}
-int KX_BlenderMaterial::_setattr(const STR_String& attr, PyObject *pyvalue)
+int KX_BlenderMaterial::_setattr(const char *attr, PyObject *pyvalue)
{
return PyObjectPlus::_setattr(attr, pyvalue);
}
@@ -790,7 +793,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
spit("Fragment shaders not supported");
mModified = true;
- Py_Return;
+ Py_RETURN_NONE;
}
if( !GLEW_ARB_vertex_shader) {
@@ -798,14 +801,14 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
spit("Vertex shaders not supported");
mModified = true;
- Py_Return;
+ Py_RETURN_NONE;
}
if(!GLEW_ARB_shader_objects) {
if(!mModified)
spit("GLSL not supported");
mModified = true;
- Py_Return;
+ Py_RETURN_NONE;
}
else {
// returns Py_None on error
@@ -838,7 +841,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, getShader , "getShader()")
}
}
}
- Py_Return;
+ Py_RETURN_NONE;
}
PyErr_Format(PyExc_ValueError, "GLSL Error");
return NULL;
@@ -910,7 +913,7 @@ KX_PYMETHODDEF_DOC( KX_BlenderMaterial, setBlending , "setBlending( GameLogic.sr
return NULL;
}
mUserDefBlend = true;
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
}
diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h
index 6e5db1b56c1..2cf623dbd85 100644
--- a/source/gameengine/Ketsji/KX_BlenderMaterial.h
+++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h
@@ -82,8 +82,8 @@ public:
);
// --------------------------------
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *pyvalue);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *pyvalue);
KX_PYMETHOD_DOC( KX_BlenderMaterial, getShader );
KX_PYMETHOD_DOC( KX_BlenderMaterial, getMaterialIndex );
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
index 534c48661b7..062e9f7df50 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
@@ -384,10 +384,10 @@ SG_Controller* KX_BulletPhysicsController::GetReplica(class SG_Node* destnode)
childit!= destnode->GetSGChildren().end();
++childit
) {
- KX_GameObject *clientgameobj = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject());
- if (clientgameobj)
+ KX_GameObject *clientgameobj_child = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject());
+ if (clientgameobj_child)
{
- parentKxCtrl = (KX_BulletPhysicsController*)clientgameobj->GetPhysicsController();
+ parentKxCtrl = (KX_BulletPhysicsController*)clientgameobj_child->GetPhysicsController();
parentctrl = parentKxCtrl;
ccdParent = parentKxCtrl;
}
diff --git a/source/gameengine/Ketsji/KX_CDActuator.cpp b/source/gameengine/Ketsji/KX_CDActuator.cpp
index a5d7f6d799a..ef7883910fd 100644
--- a/source/gameengine/Ketsji/KX_CDActuator.cpp
+++ b/source/gameengine/Ketsji/KX_CDActuator.cpp
@@ -197,9 +197,11 @@ PyMethodDef KX_CDActuator::Methods[] = {
{NULL,NULL,NULL,NULL} //Sentinel
};
+PyAttributeDef KX_CDActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
-
-PyObject* KX_CDActuator::_getattr(const STR_String& attr)
+PyObject* KX_CDActuator::_getattr(const char *attr)
{
_getattr_up(SCA_IActuator);
}
@@ -210,7 +212,7 @@ PyObject* KX_CDActuator::_getattr(const STR_String& attr)
PyObject* KX_CDActuator::PyStartCD(PyObject* self, PyObject* args, PyObject* kwds)
{
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PLAY);
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -218,7 +220,7 @@ PyObject* KX_CDActuator::PyStartCD(PyObject* self, PyObject* args, PyObject* kwd
PyObject* KX_CDActuator::PyPauseCD(PyObject* self, PyObject* args, PyObject* kwds)
{
SND_CDObject::Instance()->SetPlaystate(SND_MUST_PAUSE);
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -226,7 +228,7 @@ PyObject* KX_CDActuator::PyPauseCD(PyObject* self, PyObject* args, PyObject* kwd
PyObject* KX_CDActuator::PyStopCD(PyObject* self, PyObject* args, PyObject* kwds)
{
SND_CDObject::Instance()->SetPlaystate(SND_MUST_STOP);
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -239,7 +241,7 @@ PyObject* KX_CDActuator::PySetGain(PyObject* self, PyObject* args, PyObject* kwd
SND_CDObject::Instance()->SetGain(gain);
- Py_Return;
+ Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_CDActuator.h b/source/gameengine/Ketsji/KX_CDActuator.h
index f46dd99b6dc..393c49083f9 100644
--- a/source/gameengine/Ketsji/KX_CDActuator.h
+++ b/source/gameengine/Ketsji/KX_CDActuator.h
@@ -81,7 +81,7 @@ public:
/* Python interface --------------------------------------------------- */
/* -------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
KX_PYMETHOD(KX_CDActuator,StartCD);
KX_PYMETHOD(KX_CDActuator,PauseCD);
diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp
index fb91c793765..5caac2fc670 100644
--- a/source/gameengine/Ketsji/KX_Camera.cpp
+++ b/source/gameengine/Ketsji/KX_Camera.cpp
@@ -470,19 +470,23 @@ int KX_Camera::GetViewportTop() const
PyMethodDef KX_Camera::Methods[] = {
KX_PYMETHODTABLE(KX_Camera, sphereInsideFrustum),
- KX_PYMETHODTABLE(KX_Camera, boxInsideFrustum),
- KX_PYMETHODTABLE(KX_Camera, pointInsideFrustum),
- KX_PYMETHODTABLE(KX_Camera, getCameraToWorld),
- KX_PYMETHODTABLE(KX_Camera, getWorldToCamera),
- KX_PYMETHODTABLE(KX_Camera, getProjectionMatrix),
- KX_PYMETHODTABLE(KX_Camera, setProjectionMatrix),
- KX_PYMETHODTABLE(KX_Camera, enableViewport),
+ KX_PYMETHODTABLE_O(KX_Camera, boxInsideFrustum),
+ KX_PYMETHODTABLE_O(KX_Camera, pointInsideFrustum),
+ KX_PYMETHODTABLE_NOARGS(KX_Camera, getCameraToWorld),
+ KX_PYMETHODTABLE_NOARGS(KX_Camera, getWorldToCamera),
+ KX_PYMETHODTABLE_NOARGS(KX_Camera, getProjectionMatrix),
+ KX_PYMETHODTABLE_O(KX_Camera, setProjectionMatrix),
+ KX_PYMETHODTABLE_O(KX_Camera, enableViewport),
KX_PYMETHODTABLE(KX_Camera, setViewport),
- KX_PYMETHODTABLE(KX_Camera, setOnTop),
+ KX_PYMETHODTABLE_NOARGS(KX_Camera, setOnTop),
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_Camera::Attributes[] = {
+ { NULL } //Sentinel
+};
+
char KX_Camera::doc[] = "Module KX_Camera\n\n"
"Constants:\n"
"\tINSIDE\n"
@@ -538,48 +542,48 @@ PyParentObject KX_Camera::Parents[] = {
NULL
};
-PyObject* KX_Camera::_getattr(const STR_String& attr)
+PyObject* KX_Camera::_getattr(const char *attr)
{
- if (attr == "INSIDE")
+ if (!strcmp(attr, "INSIDE"))
return PyInt_FromLong(INSIDE); /* new ref */
- if (attr == "OUTSIDE")
+ if (!strcmp(attr, "OUTSIDE"))
return PyInt_FromLong(OUTSIDE); /* new ref */
- if (attr == "INTERSECT")
+ if (!strcmp(attr, "INTERSECT"))
return PyInt_FromLong(INTERSECT); /* new ref */
- if (attr == "lens")
+ if (!strcmp(attr, "lens"))
return PyFloat_FromDouble(GetLens()); /* new ref */
- if (attr == "near")
+ if (!strcmp(attr, "near"))
return PyFloat_FromDouble(GetCameraNear()); /* new ref */
- if (attr == "far")
+ if (!strcmp(attr, "far"))
return PyFloat_FromDouble(GetCameraFar()); /* new ref */
- if (attr == "frustum_culling")
+ if (!strcmp(attr, "frustum_culling"))
return PyInt_FromLong(m_frustum_culling); /* new ref */
- if (attr == "perspective")
+ if (!strcmp(attr, "perspective"))
return PyInt_FromLong(m_camdata.m_perspective); /* new ref */
- if (attr == "projection_matrix")
+ if (!strcmp(attr, "projection_matrix"))
return PyObjectFrom(GetProjectionMatrix()); /* new ref */
- if (attr == "modelview_matrix")
+ if (!strcmp(attr, "modelview_matrix"))
return PyObjectFrom(GetModelviewMatrix()); /* new ref */
- if (attr == "camera_to_world")
+ if (!strcmp(attr, "camera_to_world"))
return PyObjectFrom(GetCameraToWorld()); /* new ref */
- if (attr == "world_to_camera")
+ if (!strcmp(attr, "world_to_camera"))
return PyObjectFrom(GetWorldToCamera()); /* new ref */
_getattr_up(KX_GameObject);
}
-int KX_Camera::_setattr(const STR_String &attr, PyObject *pyvalue)
+int KX_Camera::_setattr(const char *attr, PyObject *pyvalue)
{
if (PyInt_Check(pyvalue))
{
- if (attr == "frustum_culling")
+ if (!strcmp(attr, "frustum_culling"))
{
m_frustum_culling = PyInt_AsLong(pyvalue);
return 0;
}
- if (attr == "perspective")
+ if (!strcmp(attr, "perspective"))
{
m_camdata.m_perspective = PyInt_AsLong(pyvalue);
return 0;
@@ -588,19 +592,19 @@ int KX_Camera::_setattr(const STR_String &attr, PyObject *pyvalue)
if (PyFloat_Check(pyvalue))
{
- if (attr == "lens")
+ if (!strcmp(attr, "lens"))
{
m_camdata.m_lens = PyFloat_AsDouble(pyvalue);
m_set_projection_matrix = false;
return 0;
}
- if (attr == "near")
+ if (!strcmp(attr, "near"))
{
m_camdata.m_clipstart = PyFloat_AsDouble(pyvalue);
m_set_projection_matrix = false;
return 0;
}
- if (attr == "far")
+ if (!strcmp(attr, "far"))
{
m_camdata.m_clipend = PyFloat_AsDouble(pyvalue);
m_set_projection_matrix = false;
@@ -610,7 +614,7 @@ int KX_Camera::_setattr(const STR_String &attr, PyObject *pyvalue)
if (PyObject_IsMT_Matrix(pyvalue, 4))
{
- if (attr == "projection_matrix")
+ if (!strcmp(attr, "projection_matrix"))
{
MT_Matrix4x4 mat;
if (PyMatTo(pyvalue, mat))
@@ -624,7 +628,7 @@ int KX_Camera::_setattr(const STR_String &attr, PyObject *pyvalue)
return KX_GameObject::_setattr(attr, pyvalue);
}
-KX_PYMETHODDEF_DOC(KX_Camera, sphereInsideFrustum,
+KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, sphereInsideFrustum,
"sphereInsideFrustum(center, radius) -> Integer\n"
"\treturns INSIDE, OUTSIDE or INTERSECT if the given sphere is\n"
"\tinside/outside/intersects this camera's viewing frustum.\n\n"
@@ -658,7 +662,7 @@ KX_PYMETHODDEF_DOC(KX_Camera, sphereInsideFrustum,
return NULL;
}
-KX_PYMETHODDEF_DOC(KX_Camera, boxInsideFrustum,
+KX_PYMETHODDEF_DOC_O(KX_Camera, boxInsideFrustum,
"boxInsideFrustum(box) -> Integer\n"
"\treturns INSIDE, OUTSIDE or INTERSECT if the given box is\n"
"\tinside/outside/intersects this camera's viewing frustum.\n\n"
@@ -683,34 +687,27 @@ KX_PYMETHODDEF_DOC(KX_Camera, boxInsideFrustum,
"\t\t# Box is outside the frustum !\n"
)
{
- PyObject *pybox;
- if (PyArg_ParseTuple(args, "O", &pybox))
+ unsigned int num_points = PySequence_Size(value);
+ if (num_points != 8)
{
- unsigned int num_points = PySequence_Size(pybox);
- if (num_points != 8)
- {
- PyErr_Format(PyExc_TypeError, "boxInsideFrustum: Expected eight (8) points, got %d", num_points);
+ PyErr_Format(PyExc_TypeError, "boxInsideFrustum: Expected eight (8) points, got %d", num_points);
+ return NULL;
+ }
+
+ MT_Point3 box[8];
+ for (unsigned int p = 0; p < 8 ; p++)
+ {
+ PyObject *item = PySequence_GetItem(value, p); /* new ref */
+ bool error = !PyVecTo(item, box[p]);
+ Py_DECREF(item);
+ if (error)
return NULL;
- }
-
- MT_Point3 box[8];
- for (unsigned int p = 0; p < 8 ; p++)
- {
- PyObject *item = PySequence_GetItem(pybox, p); /* new ref */
- bool error = !PyVecTo(item, box[p]);
- Py_DECREF(item);
- if (error)
- return NULL;
- }
-
- return PyInt_FromLong(BoxInsideFrustum(box)); /* new ref */
}
- PyErr_SetString(PyExc_TypeError, "boxInsideFrustum: Expected argument: list of points.");
- return NULL;
+ return PyInt_FromLong(BoxInsideFrustum(box)); /* new ref */
}
-KX_PYMETHODDEF_DOC(KX_Camera, pointInsideFrustum,
+KX_PYMETHODDEF_DOC_O(KX_Camera, pointInsideFrustum,
"pointInsideFrustum(point) -> Bool\n"
"\treturns 1 if the given point is inside this camera's viewing frustum.\n\n"
"\tpoint = The point to test (in world coordinates.)\n\n"
@@ -727,7 +724,7 @@ KX_PYMETHODDEF_DOC(KX_Camera, pointInsideFrustum,
)
{
MT_Point3 point;
- if (PyVecArgTo(args, point))
+ if (PyVecTo(value, point))
{
return PyInt_FromLong(PointInsideFrustum(point)); /* new ref */
}
@@ -736,7 +733,7 @@ KX_PYMETHODDEF_DOC(KX_Camera, pointInsideFrustum,
return NULL;
}
-KX_PYMETHODDEF_DOC(KX_Camera, getCameraToWorld,
+KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, getCameraToWorld,
"getCameraToWorld() -> Matrix4x4\n"
"\treturns the camera to world transformation matrix, as a list of four lists of four values.\n\n"
"\tie: [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]])\n"
@@ -745,7 +742,7 @@ KX_PYMETHODDEF_DOC(KX_Camera, getCameraToWorld,
return PyObjectFrom(GetCameraToWorld()); /* new ref */
}
-KX_PYMETHODDEF_DOC(KX_Camera, getWorldToCamera,
+KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, getWorldToCamera,
"getWorldToCamera() -> Matrix4x4\n"
"\treturns the world to camera transformation matrix, as a list of four lists of four values.\n\n"
"\tie: [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]])\n"
@@ -754,7 +751,7 @@ KX_PYMETHODDEF_DOC(KX_Camera, getWorldToCamera,
return PyObjectFrom(GetWorldToCamera()); /* new ref */
}
-KX_PYMETHODDEF_DOC(KX_Camera, getProjectionMatrix,
+KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, getProjectionMatrix,
"getProjectionMatrix() -> Matrix4x4\n"
"\treturns this camera's projection matrix, as a list of four lists of four values.\n\n"
"\tie: [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]])\n"
@@ -763,7 +760,7 @@ KX_PYMETHODDEF_DOC(KX_Camera, getProjectionMatrix,
return PyObjectFrom(GetProjectionMatrix()); /* new ref */
}
-KX_PYMETHODDEF_DOC(KX_Camera, setProjectionMatrix,
+KX_PYMETHODDEF_DOC_O(KX_Camera, setProjectionMatrix,
"setProjectionMatrix(MT_Matrix4x4 m) -> None\n"
"\tSets this camera's projection matrix\n"
"\n"
@@ -805,56 +802,50 @@ KX_PYMETHODDEF_DOC(KX_Camera, setProjectionMatrix,
"\tcam = co.getOwner()\n"
"\tcam.setProjectionMatrix(Perspective(-1.0, 1.0, -1.0, 1.0, 0.1, 1))\n")
{
- PyObject *pymat;
- if (PyArg_ParseTuple(args, "O", &pymat))
+ MT_Matrix4x4 mat;
+ if (!PyMatTo(value, mat))
{
- MT_Matrix4x4 mat;
- if (PyMatTo(pymat, mat))
- {
- SetProjectionMatrix(mat);
- Py_Return;
- }
+ PyErr_SetString(PyExc_TypeError, "setProjectionMatrix: Expected 4x4 list as matrix argument.");
+ return NULL;
}
-
- PyErr_SetString(PyExc_TypeError, "setProjectionMatrix: Expected 4x4 list as matrix argument.");
- return NULL;
+
+ SetProjectionMatrix(mat);
+ Py_RETURN_NONE;
}
-KX_PYMETHODDEF_DOC(KX_Camera, enableViewport,
+KX_PYMETHODDEF_DOC_O(KX_Camera, enableViewport,
"enableViewport(viewport)\n"
"Sets this camera's viewport status\n"
)
{
- int viewport;
- if (PyArg_ParseTuple(args,"i",&viewport))
- {
- if(viewport)
- EnableViewport(true);
- else
- EnableViewport(false);
- }
- else {
+ int viewport = PyObject_IsTrue(value);
+
+ if (viewport == -1) {
+ PyErr_SetString(PyExc_ValueError, "expected True/False or 0/1");
return NULL;
}
- Py_Return;
+ if(viewport)
+ EnableViewport(true);
+ else
+ EnableViewport(false);
+
+ Py_RETURN_NONE;
}
-KX_PYMETHODDEF_DOC(KX_Camera, setViewport,
+KX_PYMETHODDEF_DOC_VARARGS(KX_Camera, setViewport,
"setViewport(left, bottom, right, top)\n"
"Sets this camera's viewport\n")
{
int left, bottom, right, top;
- if (PyArg_ParseTuple(args,"iiii",&left, &bottom, &right, &top))
- {
- SetViewport(left, bottom, right, top);
- } else {
+ if (!PyArg_ParseTuple(args,"iiii:setViewport",&left, &bottom, &right, &top))
return NULL;
- }
- Py_Return;
+
+ SetViewport(left, bottom, right, top);
+ Py_RETURN_NONE;
}
-KX_PYMETHODDEF_DOC(KX_Camera, setOnTop,
+KX_PYMETHODDEF_DOC_NOARGS(KX_Camera, setOnTop,
"setOnTop()\n"
"Sets this camera's viewport on top\n")
{
@@ -863,5 +854,5 @@ KX_PYMETHODDEF_DOC(KX_Camera, setOnTop,
scene = KX_GetActiveScene();
MT_assert(scene);
scene->SetCameraOnTop(this);
- Py_Return;
+ Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h
index 75d574cd697..efd18f99390 100644
--- a/source/gameengine/Ketsji/KX_Camera.h
+++ b/source/gameengine/Ketsji/KX_Camera.h
@@ -126,7 +126,7 @@ protected:
void ExtractFrustumSphere();
public:
- typedef enum { INSIDE, INTERSECT, OUTSIDE } ;
+ enum { INSIDE, INTERSECT, OUTSIDE } ;
KX_Camera(void* sgReplicationInfo,SG_Callbacks callbacks,const RAS_CameraData& camdata, bool frustum_culling = true, PyTypeObject *T = &Type);
virtual ~KX_Camera();
@@ -257,21 +257,21 @@ public:
int GetViewportTop() const;
- KX_PYMETHOD_DOC(KX_Camera, sphereInsideFrustum);
- KX_PYMETHOD_DOC(KX_Camera, boxInsideFrustum);
- KX_PYMETHOD_DOC(KX_Camera, pointInsideFrustum);
+ KX_PYMETHOD_DOC_VARARGS(KX_Camera, sphereInsideFrustum);
+ KX_PYMETHOD_DOC_O(KX_Camera, boxInsideFrustum);
+ KX_PYMETHOD_DOC_O(KX_Camera, pointInsideFrustum);
- KX_PYMETHOD_DOC(KX_Camera, getCameraToWorld);
- KX_PYMETHOD_DOC(KX_Camera, getWorldToCamera);
- KX_PYMETHOD_DOC(KX_Camera, getProjectionMatrix);
- KX_PYMETHOD_DOC(KX_Camera, setProjectionMatrix);
+ KX_PYMETHOD_DOC_NOARGS(KX_Camera, getCameraToWorld);
+ KX_PYMETHOD_DOC_NOARGS(KX_Camera, getWorldToCamera);
+ KX_PYMETHOD_DOC_NOARGS(KX_Camera, getProjectionMatrix);
+ KX_PYMETHOD_DOC_O(KX_Camera, setProjectionMatrix);
- KX_PYMETHOD_DOC(KX_Camera, enableViewport);
- KX_PYMETHOD_DOC(KX_Camera, setViewport);
- KX_PYMETHOD_DOC(KX_Camera, setOnTop);
+ KX_PYMETHOD_DOC_O(KX_Camera, enableViewport);
+ KX_PYMETHOD_DOC_VARARGS(KX_Camera, setViewport);
+ KX_PYMETHOD_DOC_NOARGS(KX_Camera, setOnTop);
- virtual PyObject* _getattr(const STR_String& attr); /* lens, near, far, projection_matrix */
- virtual int _setattr(const STR_String& attr, PyObject *pyvalue);
+ virtual PyObject* _getattr(const char *attr); /* lens, near, far, projection_matrix */
+ virtual int _setattr(const char *attr, PyObject *pyvalue);
};
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp
index 4d24e83843e..30ecc5ad441 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.cpp
+++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp
@@ -33,6 +33,7 @@
#include "KX_CameraActuator.h"
#include <iostream>
#include <math.h>
+#include <float.h>
#include "KX_GameObject.h"
#include "PyObjectPlus.h"
@@ -52,9 +53,9 @@ STR_String KX_CameraActuator::Y_AXIS_STRING = "y";
KX_CameraActuator::KX_CameraActuator(
SCA_IObject* gameobj,
SCA_IObject *obj,
- MT_Scalar hght,
- MT_Scalar minhght,
- MT_Scalar maxhght,
+ float hght,
+ float minhght,
+ float maxhght,
bool xytog,
PyTypeObject* T
):
@@ -397,6 +398,7 @@ PyParentObject KX_CameraActuator::Parents[] = {
};
PyMethodDef KX_CameraActuator::Methods[] = {
+ // ---> deprecated (all)
{"setObject",(PyCFunction) KX_CameraActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc},
{"getObject",(PyCFunction) KX_CameraActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc},
{"setMin" ,(PyCFunction) KX_CameraActuator::sPySetMin, METH_VARARGS, (PY_METHODCHAR)SetMin_doc},
@@ -410,9 +412,54 @@ PyMethodDef KX_CameraActuator::Methods[] = {
{NULL,NULL,NULL,NULL} //Sentinel
};
-PyObject* KX_CameraActuator::_getattr(const STR_String& attr) {
+PyAttributeDef KX_CameraActuator::Attributes[] = {
+ KX_PYATTRIBUTE_FLOAT_RW("min",-FLT_MAX,FLT_MAX,KX_CameraActuator,m_minHeight),
+ KX_PYATTRIBUTE_FLOAT_RW("max",-FLT_MAX,FLT_MAX,KX_CameraActuator,m_maxHeight),
+ KX_PYATTRIBUTE_FLOAT_RW("height",-FLT_MAX,FLT_MAX,KX_CameraActuator,m_height),
+ KX_PYATTRIBUTE_BOOL_RW("xy",KX_CameraActuator,m_x),
+ {NULL}
+};
+
+PyObject* KX_CameraActuator::_getattr(const char *attr) {
+ PyObject* object;
+
+ if (!strcmp(attr, "object")) {
+ if (!m_ob) Py_RETURN_NONE;
+ else return m_ob->AddRef();
+ }
+
+ object = _getattr_self(Attributes, this, attr);
+ if (object != NULL)
+ return object;
_getattr_up(SCA_IActuator);
}
+
+int KX_CameraActuator::_setattr(const char *attr, PyObject* value) {
+ int ret;
+
+ if (!strcmp(attr, "object")) {
+ KX_GameObject *gameobj;
+
+ if (!ConvertPythonToGameObject(value, &gameobj, true))
+ return 1; // ConvertPythonToGameObject sets the error
+
+ if (m_ob != NULL)
+ m_ob->UnregisterActuator(this);
+
+ m_ob = (SCA_IObject*)gameobj;
+
+ if (m_ob)
+ m_ob->RegisterActuator(this);
+
+ return 0;
+ }
+
+ ret = _setattr_self(Attributes, this, attr, value);
+ if (ret >= 0)
+ return ret;
+ return SCA_IActuator::_setattr(attr, value);
+}
+
/* get obj ---------------------------------------------------------- */
const char KX_CameraActuator::GetObject_doc[] =
"getObject(name_only = 1)\n"
@@ -421,6 +468,9 @@ const char KX_CameraActuator::GetObject_doc[] =
PyObject* KX_CameraActuator::PyGetObject(PyObject* self, PyObject* args)
{
int ret_name_only = 1;
+
+ ShowDeprecationWarning("getObject()", "the object property");
+
if (!PyArg_ParseTuple(args, "|i", &ret_name_only))
return NULL;
@@ -441,6 +491,8 @@ PyObject* KX_CameraActuator::PySetObject(PyObject* self, PyObject* value)
{
KX_GameObject *gameobj;
+ ShowDeprecationWarning("setObject()", "the object property");
+
if (!ConvertPythonToGameObject(value, &gameobj, true))
return NULL; // ConvertPythonToGameObject sets the error
@@ -462,6 +514,7 @@ PyObject* KX_CameraActuator::PyGetMin(PyObject* self,
PyObject* args,
PyObject* kwds)
{
+ ShowDeprecationWarning("getMin()", "the min property");
return PyFloat_FromDouble(m_minHeight);
}
/* set min ---------------------------------------------------------- */
@@ -472,11 +525,12 @@ PyObject* KX_CameraActuator::PySetMin(PyObject* self,
PyObject* args,
PyObject* kwds)
{
+ ShowDeprecationWarning("setMin()", "the min property");
float min;
if(PyArg_ParseTuple(args,"f", &min))
{
m_minHeight = min;
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
}
@@ -488,6 +542,7 @@ PyObject* KX_CameraActuator::PyGetMax(PyObject* self,
PyObject* args,
PyObject* kwds)
{
+ ShowDeprecationWarning("getMax()", "the max property");
return PyFloat_FromDouble(m_maxHeight);
}
/* set min ---------------------------------------------------------- */
@@ -498,11 +553,12 @@ PyObject* KX_CameraActuator::PySetMax(PyObject* self,
PyObject* args,
PyObject* kwds)
{
+ ShowDeprecationWarning("getMax()", "the max property");
float max;
if(PyArg_ParseTuple(args,"f", &max))
{
m_maxHeight = max;
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
}
@@ -514,6 +570,7 @@ PyObject* KX_CameraActuator::PyGetHeight(PyObject* self,
PyObject* args,
PyObject* kwds)
{
+ ShowDeprecationWarning("getHeight()", "the height property");
return PyFloat_FromDouble(m_height);
}
/* set height ---------------------------------------------------------- */
@@ -524,11 +581,12 @@ PyObject* KX_CameraActuator::PySetHeight(PyObject* self,
PyObject* args,
PyObject* kwds)
{
+ ShowDeprecationWarning("getHeight()", "the height property");
float height;
if(PyArg_ParseTuple(args,"f", &height))
{
m_height = height;
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
}
@@ -541,11 +599,12 @@ PyObject* KX_CameraActuator::PySetXY(PyObject* self,
PyObject* args,
PyObject* kwds)
{
+ ShowDeprecationWarning("setXY()", "the xy property");
int value;
if(PyArg_ParseTuple(args,"i", &value))
{
m_x = value != 0;
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
}
@@ -559,6 +618,7 @@ PyObject* KX_CameraActuator::PyGetXY(PyObject* self,
PyObject* args,
PyObject* kwds)
{
+ ShowDeprecationWarning("getXY()", "the xy property");
return PyInt_FromLong(m_x);
}
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.h b/source/gameengine/Ketsji/KX_CameraActuator.h
index d53d12b3b82..3b08536fc21 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.h
+++ b/source/gameengine/Ketsji/KX_CameraActuator.h
@@ -59,13 +59,13 @@ private :
//const MT_Scalar m_maxHeight;
/** height (float), */
- MT_Scalar m_height;
+ float m_height;
/** min (float), */
- MT_Scalar m_minHeight;
+ float m_minHeight;
/** max (float), */
- MT_Scalar m_maxHeight;
+ float m_maxHeight;
/** xy toggle (pick one): true == x, false == y */
bool m_x;
@@ -88,9 +88,9 @@ private :
SCA_IObject *gameobj,
//const CValue *ob,
SCA_IObject *ob,
- MT_Scalar hght,
- MT_Scalar minhght,
- MT_Scalar maxhght,
+ float hght,
+ float minhght,
+ float maxhght,
bool xytog,
PyTypeObject* T=&Type
@@ -120,8 +120,9 @@ private :
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
-
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject* value);
+
/* set object to look at */
KX_PYMETHOD_DOC_O(KX_CameraActuator,SetObject);
/* get current object */
diff --git a/source/gameengine/Ketsji/KX_ClientObjectInfo.h b/source/gameengine/Ketsji/KX_ClientObjectInfo.h
index 5e8af0f040c..7345edb054b 100644
--- a/source/gameengine/Ketsji/KX_ClientObjectInfo.h
+++ b/source/gameengine/Ketsji/KX_ClientObjectInfo.h
@@ -29,7 +29,10 @@
#ifndef __KX_CLIENTOBJECT_INFO_H
#define __KX_CLIENTOBJECT_INFO_H
+/* Note, the way this works with/without sumo is a bit odd */
+#ifdef USE_SUMO_SOLID
#include <SM_Object.h>
+#endif //USE_SUMO_SOLID
#include <list>
@@ -38,7 +41,10 @@ class KX_GameObject;
/**
* Client Type and Additional Info. This structure can be use instead of a bare void* pointer, for safeness, and additional info for callbacks
*/
-struct KX_ClientObjectInfo : public SM_ClientObject
+struct KX_ClientObjectInfo
+#ifdef USE_SUMO_SOLID
+ : public SM_ClientObject
+#endif
{
enum clienttype {
STATIC,
@@ -52,14 +58,18 @@ struct KX_ClientObjectInfo : public SM_ClientObject
std::list<SCA_ISensor*> m_sensors;
public:
KX_ClientObjectInfo(KX_GameObject *gameobject, clienttype type = STATIC, void *auxilary_info = NULL) :
+#ifdef USE_SUMO_SOLID
SM_ClientObject(),
+#endif
m_type(type),
m_gameobject(gameobject),
m_auxilary_info(auxilary_info)
{}
- KX_ClientObjectInfo(const KX_ClientObjectInfo &copy)
- : SM_ClientObject(copy),
+ KX_ClientObjectInfo(const KX_ClientObjectInfo &copy) :
+#ifdef USE_SUMO_SOLID
+ SM_ClientObject(copy),
+#endif
m_type(copy.m_type),
m_gameobject(copy.m_gameobject),
m_auxilary_info(copy.m_auxilary_info)
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
index 76357e9c58f..fba9544d702 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
@@ -56,9 +56,9 @@ KX_ConstraintActuator::KX_ConstraintActuator(SCA_IObject *gameobj,
int option,
char *property,
PyTypeObject* T) :
+ SCA_IActuator(gameobj, T),
m_refDirection(refDir),
- m_currentTime(0),
- SCA_IActuator(gameobj, T)
+ m_currentTime(0)
{
m_posDampTime = posDampTime;
m_rotDampTime = rotDampTime;
@@ -612,7 +612,11 @@ PyMethodDef KX_ConstraintActuator::Methods[] = {
{NULL,NULL} //Sentinel
};
-PyObject* KX_ConstraintActuator::_getattr(const STR_String& attr) {
+PyAttributeDef KX_ConstraintActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* KX_ConstraintActuator::_getattr(const char *attr) {
_getattr_up(SCA_IActuator);
}
@@ -633,7 +637,7 @@ PyObject* KX_ConstraintActuator::PySetDamp(PyObject* self,
m_posDampTime = dampArg;
if (m_posDampTime < 0) m_posDampTime = 0;
- Py_Return;
+ Py_RETURN_NONE;
}
/* 3. getDamp */
const char KX_ConstraintActuator::GetDamp_doc[] =
@@ -660,7 +664,7 @@ PyObject* KX_ConstraintActuator::PySetRotDamp(PyObject* self,
m_rotDampTime = dampArg;
if (m_rotDampTime < 0) m_rotDampTime = 0;
- Py_Return;
+ Py_RETURN_NONE;
}
/* 3. getRotDamp */
const char KX_ConstraintActuator::GetRotDamp_doc[] =
@@ -695,7 +699,7 @@ PyObject* KX_ConstraintActuator::PySetDirection(PyObject* self,
}
m_refDirection = dir/len;
- Py_Return;
+ Py_RETURN_NONE;
}
/* 3. getDirection */
const char KX_ConstraintActuator::GetDirection_doc[] =
@@ -730,7 +734,7 @@ PyObject* KX_ConstraintActuator::PySetOption(PyObject* self,
m_option = option;
- Py_Return;
+ Py_RETURN_NONE;
}
/* 3. getOption */
const char KX_ConstraintActuator::GetOption_doc[] =
@@ -759,7 +763,7 @@ PyObject* KX_ConstraintActuator::PySetTime(PyObject* self,
t = 0;
m_activeTime = t;
- Py_Return;
+ Py_RETURN_NONE;
}
/* 3. getTime */
const char KX_ConstraintActuator::GetTime_doc[] =
@@ -789,7 +793,7 @@ PyObject* KX_ConstraintActuator::PySetProperty(PyObject* self,
m_property[sizeof(m_property)-1] = 0;
}
- Py_Return;
+ Py_RETURN_NONE;
}
/* 3. getProperty */
const char KX_ConstraintActuator::GetProperty_doc[] =
@@ -829,7 +833,7 @@ PyObject* KX_ConstraintActuator::PySetMin(PyObject* self,
break;
}
- Py_Return;
+ Py_RETURN_NONE;
}
/* 5. getDistance */
const char KX_ConstraintActuator::GetDistance_doc[] =
@@ -874,7 +878,7 @@ PyObject* KX_ConstraintActuator::PySetMax(PyObject* self,
break;
}
- Py_Return;
+ Py_RETURN_NONE;
}
/* 7. getRayLength */
const char KX_ConstraintActuator::GetRayLength_doc[] =
@@ -918,7 +922,7 @@ PyObject* KX_ConstraintActuator::PySetLimit(PyObject* self,
if (IsValidMode((KX_CONSTRAINTTYPE)locrotArg)) m_locrot = locrotArg;
- Py_Return;
+ Py_RETURN_NONE;
}
/* 9. getLimit */
const char KX_ConstraintActuator::GetLimit_doc[] =
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h
index 28b9b1e6a0b..132b8a7328a 100644
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.h
+++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h
@@ -142,7 +142,7 @@ protected:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
KX_PYMETHOD_DOC(KX_ConstraintActuator,SetDamp);
KX_PYMETHOD_DOC_NOARGS(KX_ConstraintActuator,GetDamp);
diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp
index c9095ff34f6..f014c1896fe 100644
--- a/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.cpp
@@ -92,32 +92,30 @@ PyParentObject KX_ConstraintWrapper::Parents[] = {
NULL
};
-PyObject* KX_ConstraintWrapper::_getattr(const STR_String& attr)
+PyObject* KX_ConstraintWrapper::_getattr(const char *attr)
{
//here you can search for existing data members (like mass,friction etc.)
_getattr_up(PyObjectPlus);
}
-int KX_ConstraintWrapper::_setattr(const STR_String& attr,PyObject* pyobj)
+int KX_ConstraintWrapper::_setattr(const char *attr,PyObject* pyobj)
{
-
- PyTypeObject* type = pyobj->ob_type;
int result = 1;
- if (type == &PyList_Type)
+ if (PyList_Check(pyobj))
{
result = 0;
}
- if (type == &PyFloat_Type)
+ if (PyFloat_Check(pyobj))
{
result = 0;
}
- if (type == &PyInt_Type)
+ if (PyInt_Check(pyobj))
{
result = 0;
}
- if (type == &PyString_Type)
+ if (PyString_Check(pyobj))
{
result = 0;
}
@@ -132,3 +130,7 @@ PyMethodDef KX_ConstraintWrapper::Methods[] = {
{"getConstraintId",(PyCFunction) KX_ConstraintWrapper::sPyGetConstraintId, METH_VARARGS},
{NULL,NULL} //Sentinel
};
+
+PyAttributeDef KX_ConstraintWrapper::Attributes[] = {
+ { NULL } //Sentinel
+};
diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h
index 79fb3dc21aa..36606d2d67b 100644
--- a/source/gameengine/Ketsji/KX_ConstraintWrapper.h
+++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h
@@ -35,8 +35,8 @@
class KX_ConstraintWrapper : public PyObjectPlus
{
Py_Header;
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
public:
KX_ConstraintWrapper(PHY_ConstraintType ctype,int constraintId,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type);
virtual ~KX_ConstraintWrapper ();
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
index 53486cecf73..3534500e619 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
@@ -32,7 +32,7 @@
/* These are defined by the build system... */
//but the build system is broken, because it doesn't allow for 2 or more defines at once.
//Please leave Sumo _AND_ Bullet enabled
-#define USE_SUMO_SOLID
+//#define USE_SUMO_SOLID // scons defines this
#define USE_BULLET
//#define USE_ODE
@@ -127,6 +127,14 @@ struct KX_ObjectProperties
/////////////////////////
+ bool m_lockXaxis;
+ bool m_lockYaxis;
+ bool m_lockZaxis;
+ bool m_lockXRotaxis;
+ bool m_lockYRotaxis;
+ bool m_lockZRotaxis;
+
+ /////////////////////////
double m_margin;
KX_BoundBoxClass m_boundclass;
union {
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index 46e46b014b5..602486e0017 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -1101,8 +1101,24 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
{
btRigidBody* rbody = physicscontroller->GetRigidBody();
- if (rbody && objprop->m_disableSleeping)
- rbody->setActivationState(DISABLE_DEACTIVATION);
+ if (rbody)
+ {
+ btVector3 linearFactor(
+ objprop->m_lockXaxis? 0 : 1,
+ objprop->m_lockYaxis? 0 : 1,
+ objprop->m_lockZaxis? 0 : 1);
+ btVector3 angularFactor(
+ objprop->m_lockXRotaxis? 0 : 1,
+ objprop->m_lockYRotaxis? 0 : 1,
+ objprop->m_lockZRotaxis? 0 : 1);
+ rbody->setLinearFactor(linearFactor);
+ rbody->setAngularFactor(angularFactor);
+
+ if (rbody && objprop->m_disableSleeping)
+ {
+ rbody->setActivationState(DISABLE_DEACTIVATION);
+ }
+ }
}
CcdPhysicsController* parentCtrl = objprop->m_dynamic_parent ? (KX_BulletPhysicsController*)objprop->m_dynamic_parent->GetPhysicsController() : 0;
diff --git a/source/gameengine/Ketsji/KX_GameActuator.cpp b/source/gameengine/Ketsji/KX_GameActuator.cpp
index 76459e46731..3c0695b5952 100644
--- a/source/gameengine/Ketsji/KX_GameActuator.cpp
+++ b/source/gameengine/Ketsji/KX_GameActuator.cpp
@@ -132,7 +132,7 @@ bool KX_GameActuator::Update()
{
char mashal_path[512];
char *marshal_buffer = NULL;
- int marshal_length;
+ unsigned int marshal_length;
FILE *fp = NULL;
pathGamePythonConfig(mashal_path);
@@ -246,6 +246,10 @@ PyMethodDef KX_GameActuator::Methods[] =
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_GameActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
+
/* getFile */
const char KX_GameActuator::GetFile_doc[] =
"getFile()\n"
@@ -270,13 +274,13 @@ PyObject* KX_GameActuator::PySetFile(PyObject* self, PyObject* args, PyObject* k
m_filename = STR_String(new_file);
- Py_Return;
+ Py_RETURN_NONE;
}
-PyObject* KX_GameActuator::_getattr(const STR_String& attr)
+PyObject* KX_GameActuator::_getattr(const char *attr)
{
_getattr_up(SCA_IActuator);
}
diff --git a/source/gameengine/Ketsji/KX_GameActuator.h b/source/gameengine/Ketsji/KX_GameActuator.h
index bb3448995dc..856fa0c24e9 100644
--- a/source/gameengine/Ketsji/KX_GameActuator.h
+++ b/source/gameengine/Ketsji/KX_GameActuator.h
@@ -77,7 +77,7 @@ protected:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
KX_PYMETHOD_DOC(KX_GameActuator,GetFile);
KX_PYMETHOD_DOC(KX_GameActuator,SetFile);
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 42316c6c873..95df9d51a26 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -521,7 +521,7 @@ KX_GameObject::UpdateMaterialData(
{
KX_BlenderMaterial *m = static_cast<KX_BlenderMaterial*>(poly);
- if (matname_hash == NULL)
+ if (matname_hash == 0)
{
m->UpdateIPO(rgba, specrgb,hard,spec,ref,emit, alpha);
// if mesh has only one material attached to it then use original hack with no need to edit vertices (better performance)
@@ -690,9 +690,9 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac)
switch (axis)
{
case 0: //x axis
- ori = MT_Vector3(orimat[0][2], orimat[1][2], orimat[2][2]); //pivot axis
+ ori.setValue(orimat[0][2], orimat[1][2], orimat[2][2]); //pivot axis
if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON) //is the vector paralell to the pivot?
- ori = MT_Vector3(orimat[0][1], orimat[1][1], orimat[2][1]); //change the pivot!
+ ori.setValue(orimat[0][1], orimat[1][1], orimat[2][1]); //change the pivot!
if (fac == 1.0) {
x = vect;
} else {
@@ -705,9 +705,9 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac)
z = x.cross(y);
break;
case 1: //y axis
- ori = MT_Vector3(orimat[0][0], orimat[1][0], orimat[2][0]);
+ ori.setValue(orimat[0][0], orimat[1][0], orimat[2][0]);
if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON)
- ori = MT_Vector3(orimat[0][2], orimat[1][2], orimat[2][2]);
+ ori.setValue(orimat[0][2], orimat[1][2], orimat[2][2]);
if (fac == 1.0) {
y = vect;
} else {
@@ -720,9 +720,9 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac)
x = y.cross(z);
break;
case 2: //z axis
- ori = MT_Vector3(orimat[0][1], orimat[1][1], orimat[2][1]);
+ ori.setValue(orimat[0][1], orimat[1][1], orimat[2][1]);
if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON)
- ori = MT_Vector3(orimat[0][0], orimat[1][0], orimat[2][0]);
+ ori.setValue(orimat[0][0], orimat[1][0], orimat[2][0]);
if (fac == 1.0) {
z = vect;
} else {
@@ -741,9 +741,9 @@ void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis, float fac)
x.normalize(); //normalize the vectors
y.normalize();
z.normalize();
- orimat = MT_Matrix3x3( x[0],y[0],z[0],
- x[1],y[1],z[1],
- x[2],y[2],z[2]);
+ orimat.setValue( x[0],y[0],z[0],
+ x[1],y[1],z[1],
+ x[2],y[2],z[2]);
if (GetSGNode()->GetSGParent() != NULL)
{
// the object is a child, adapt its local orientation so that
@@ -945,13 +945,11 @@ const MT_Vector3& KX_GameObject::NodeGetWorldScaling() const
const MT_Point3& KX_GameObject::NodeGetWorldPosition() const
{
- static MT_Point3 defaultPosition = MT_Point3(0.0, 0.0, 0.0);
-
// check on valid node in case a python controller holds a reference to a deleted object
- if (!GetSGNode())
- return defaultPosition;
-
- return GetSGNode()->GetWorldPosition();
+ if (GetSGNode())
+ return GetSGNode()->GetWorldPosition();
+ else
+ return MT_Point3(0.0, 0.0, 0.0);
}
/* Suspend/ resume: for the dynamic behaviour, there is a simple
@@ -1030,11 +1028,14 @@ PyMethodDef KX_GameObject::Methods[] = {
{"endObject",(PyCFunction) KX_GameObject::sPyEndObject, METH_NOARGS},
KX_PYMETHODTABLE(KX_GameObject, rayCastTo),
KX_PYMETHODTABLE(KX_GameObject, rayCast),
- KX_PYMETHODTABLE(KX_GameObject, getDistanceTo),
- KX_PYMETHODTABLE(KX_GameObject, getVectTo),
+ KX_PYMETHODTABLE_O(KX_GameObject, getDistanceTo),
+ KX_PYMETHODTABLE_O(KX_GameObject, getVectTo),
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_GameObject::Attributes[] = {
+ { NULL } //Sentinel
+};
/*
@@ -1124,40 +1125,39 @@ PyParentObject KX_GameObject::Parents[] = {
-PyObject* KX_GameObject::_getattr(const STR_String& attr)
+PyObject* KX_GameObject::_getattr(const char *attr)
{
if (m_pPhysicsController1)
{
- if (attr == "mass")
+ if (!strcmp(attr, "mass"))
return PyFloat_FromDouble(m_pPhysicsController1->GetMass());
}
- if (attr == "parent")
+ if (!strcmp(attr, "parent"))
{
KX_GameObject* parent = GetParent();
if (parent)
- {
- parent->AddRef();
- return parent;
- }
+ return parent->AddRef();
Py_RETURN_NONE;
}
- if (attr == "visible")
+ if (!strcmp(attr, "visible"))
return PyInt_FromLong(m_bVisible);
- if (attr == "position")
+ if (!strcmp(attr, "position"))
return PyObjectFrom(NodeGetWorldPosition());
- if (attr == "orientation")
+ if (!strcmp(attr, "orientation"))
return PyObjectFrom(NodeGetWorldOrientation());
- if (attr == "scaling")
+ if (!strcmp(attr, "scaling"))
return PyObjectFrom(NodeGetWorldScaling());
- if (attr == "name")
+ if (!strcmp(attr, "name"))
return PyString_FromString(m_name.ReadPtr());
- if (attr == "timeOffset") {
+
+ if (!strcmp(attr, "timeOffset"))
+ {
if (m_pSGNode->GetSGParent()->IsSlowParent()) {
return PyFloat_FromDouble(static_cast<KX_SlowParentRelation *>(m_pSGNode->GetSGParent()->GetParentRelation())->GetTimeOffset());
} else {
@@ -1169,18 +1169,18 @@ PyObject* KX_GameObject::_getattr(const STR_String& attr)
_getattr_up(SCA_IObject);
}
-int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr method
+int KX_GameObject::_setattr(const char *attr, PyObject *value) // _setattr method
{
- if (attr == "parent") {
- PyErr_SetString(PyExc_AttributeError, "attribute \"mass\" is read only\nUse setParent()");
+ if (!strcmp(attr, "parent")) {
+ PyErr_SetString(PyExc_AttributeError, "attribute \"parent\" is read only\nUse setParent()");
return 1;
}
if (PyInt_Check(value))
{
int val = PyInt_AsLong(value);
- if (attr == "visible")
+ if (!strcmp(attr, "visible"))
{
SetVisible(val != 0, false);
UpdateBuckets(false);
@@ -1191,7 +1191,7 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr
if (PyFloat_Check(value))
{
MT_Scalar val = PyFloat_AsDouble(value);
- if (attr == "timeOffset") {
+ if (!strcmp(attr, "timeOffset")) {
if (m_pSGNode->GetSGParent() && m_pSGNode->GetSGParent()->IsSlowParent()) {
static_cast<KX_SlowParentRelation *>(m_pSGNode->GetSGParent()->GetParentRelation())->SetTimeOffset(val);
return 0;
@@ -1199,7 +1199,7 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr
return 0;
}
}
- if (attr == "mass") {
+ if (!strcmp(attr, "mass")) {
if (m_pPhysicsController1)
m_pPhysicsController1->SetMass(val);
return 0;
@@ -1208,7 +1208,7 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr
if (PySequence_Check(value))
{
- if (attr == "orientation")
+ if (!strcmp(attr, "orientation"))
{
MT_Matrix3x3 rot;
if (PyObject_IsMT_Matrix(value, 3))
@@ -1251,7 +1251,7 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr
return 1;
}
- if (attr == "position")
+ if (!strcmp(attr, "position"))
{
MT_Point3 pos;
if (PyVecTo(value, pos))
@@ -1263,7 +1263,7 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr
return 1;
}
- if (attr == "scaling")
+ if (!strcmp(attr, "scaling"))
{
MT_Vector3 scale;
if (PyVecTo(value, scale))
@@ -1278,10 +1278,16 @@ int KX_GameObject::_setattr(const STR_String& attr, PyObject *value) // _setattr
if (PyString_Check(value))
{
- if (attr == "name")
+ if (!strcmp(attr, "name"))
{
+#if 0 // was added in revision 2832, but never took into account Object name mappings from revision 2
+ // unlikely anyone ever used this successfully , removing.
m_name = PyString_AsString(value);
return 0;
+#else
+ PyErr_SetString(PyExc_AttributeError, "object name readonly");
+ return 1;
+#endif
}
}
@@ -1295,7 +1301,7 @@ PyObject* KX_GameObject::PyApplyForce(PyObject* self, PyObject* args)
int local = 0;
PyObject* pyvect;
- if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) {
+ if (PyArg_ParseTuple(args, "O|i:applyForce", &pyvect, &local)) {
MT_Vector3 force;
if (PyVecTo(pyvect, force)) {
ApplyForce(force, (local!=0));
@@ -1310,7 +1316,7 @@ PyObject* KX_GameObject::PyApplyTorque(PyObject* self, PyObject* args)
int local = 0;
PyObject* pyvect;
- if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) {
+ if (PyArg_ParseTuple(args, "O|i:applyTorque", &pyvect, &local)) {
MT_Vector3 torque;
if (PyVecTo(pyvect, torque)) {
ApplyTorque(torque, (local!=0));
@@ -1325,7 +1331,7 @@ PyObject* KX_GameObject::PyApplyRotation(PyObject* self, PyObject* args)
int local = 0;
PyObject* pyvect;
- if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) {
+ if (PyArg_ParseTuple(args, "O|i:applyRotation", &pyvect, &local)) {
MT_Vector3 rotation;
if (PyVecTo(pyvect, rotation)) {
ApplyRotation(rotation, (local!=0));
@@ -1340,7 +1346,7 @@ PyObject* KX_GameObject::PyApplyMovement(PyObject* self, PyObject* args)
int local = 0;
PyObject* pyvect;
- if (PyArg_ParseTuple(args, "O|i", &pyvect, &local)) {
+ if (PyArg_ParseTuple(args, "O|i:applyMovement", &pyvect, &local)) {
MT_Vector3 movement;
if (PyVecTo(pyvect, movement)) {
ApplyMovement(movement, (local!=0));
@@ -1354,7 +1360,7 @@ PyObject* KX_GameObject::PyGetLinearVelocity(PyObject* self, PyObject* args)
{
// only can get the velocity if we have a physics object connected to us...
int local = 0;
- if (PyArg_ParseTuple(args,"|i",&local))
+ if (PyArg_ParseTuple(args,"|i:getLinearVelocity",&local))
{
return PyObjectFrom(GetLinearVelocity((local!=0)));
}
@@ -1369,7 +1375,7 @@ PyObject* KX_GameObject::PySetLinearVelocity(PyObject* self, PyObject* args)
int local = 0;
PyObject* pyvect;
- if (PyArg_ParseTuple(args,"O|i",&pyvect,&local)) {
+ if (PyArg_ParseTuple(args,"O|i:setLinearVelocity",&pyvect,&local)) {
MT_Vector3 velocity;
if (PyVecTo(pyvect, velocity)) {
setLinearVelocity(velocity, (local!=0));
@@ -1383,7 +1389,7 @@ PyObject* KX_GameObject::PyGetAngularVelocity(PyObject* self, PyObject* args)
{
// only can get the velocity if we have a physics object connected to us...
int local = 0;
- if (PyArg_ParseTuple(args,"|i",&local))
+ if (PyArg_ParseTuple(args,"|i:getAngularVelocity",&local))
{
return PyObjectFrom(GetAngularVelocity((local!=0)));
}
@@ -1398,7 +1404,7 @@ PyObject* KX_GameObject::PySetAngularVelocity(PyObject* self, PyObject* args)
int local = 0;
PyObject* pyvect;
- if (PyArg_ParseTuple(args,"O|i",&pyvect,&local)) {
+ if (PyArg_ParseTuple(args,"O|i:setAngularVelocity",&pyvect,&local)) {
MT_Vector3 velocity;
if (PyVecTo(pyvect, velocity)) {
setAngularVelocity(velocity, (local!=0));
@@ -1411,7 +1417,7 @@ PyObject* KX_GameObject::PySetAngularVelocity(PyObject* self, PyObject* args)
PyObject* KX_GameObject::PySetVisible(PyObject* self, PyObject* args)
{
int visible, recursive = 0;
- if (!PyArg_ParseTuple(args,"i|i",&visible, &recursive))
+ if (!PyArg_ParseTuple(args,"i|i:setVisible",&visible, &recursive))
return NULL;
SetVisible(visible ? true:false, recursive ? true:false);
@@ -1457,12 +1463,10 @@ PyObject* KX_GameObject::PySetState(PyObject* self, PyObject* value)
PyObject* KX_GameObject::PyGetVelocity(PyObject* self, PyObject* args)
{
// only can get the velocity if we have a physics object connected to us...
- MT_Vector3 velocity(0.0,0.0,0.0);
MT_Point3 point(0.0,0.0,0.0);
-
-
PyObject* pypos = NULL;
- if (PyArg_ParseTuple(args, "|O", &pypos))
+
+ if (PyArg_ParseTuple(args, "|O:getVelocity", &pypos))
{
if (pypos)
PyVecTo(pypos, point);
@@ -1473,10 +1477,11 @@ PyObject* KX_GameObject::PyGetVelocity(PyObject* self, PyObject* args)
if (m_pPhysicsController1)
{
- velocity = m_pPhysicsController1->GetVelocity(point);
+ return PyObjectFrom(m_pPhysicsController1->GetVelocity(point));
+ }
+ else {
+ return PyObjectFrom(MT_Vector3(0.0,0.0,0.0));
}
-
- return PyObjectFrom(velocity);
}
@@ -1518,10 +1523,7 @@ PyObject* KX_GameObject::PyGetParent(PyObject* self)
{
KX_GameObject* parent = this->GetParent();
if (parent)
- {
- parent->AddRef();
- return parent;
- }
+ return parent->AddRef();
Py_RETURN_NONE;
}
@@ -1590,7 +1592,7 @@ PyObject* KX_GameObject::PyGetMesh(PyObject* self, PyObject* args)
{
int mesh = 0;
- if (!PyArg_ParseTuple(args, "|i", &mesh))
+ if (!PyArg_ParseTuple(args, "|i:getMesh", &mesh))
return NULL; // python sets a simple error
if (((unsigned int)mesh < m_meshes.size()) && mesh >= 0)
@@ -1636,7 +1638,7 @@ PyObject* KX_GameObject::PyApplyImpulse(PyObject* self, PyObject* args)
return NULL;
}
- if (PyArg_ParseTuple(args, "OO", &pyattach, &pyimpulse))
+ if (PyArg_ParseTuple(args, "OO:applyImpulse", &pyattach, &pyimpulse))
{
MT_Point3 attach;
MT_Vector3 impulse;
@@ -1703,7 +1705,7 @@ PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* self, PyObject* args)
int axis = 2; //z axis is the default
float fac = 1.0;
- if (PyArg_ParseTuple(args,"O|if",&pyvect,&axis, &fac))
+ if (PyArg_ParseTuple(args,"O|if:alignAxisToVect",&pyvect,&axis, &fac))
{
MT_Vector3 vect;
if (PyVecTo(pyvect, vect))
@@ -1771,19 +1773,18 @@ PyObject* KX_GameObject::PyGetPropertyNames(PyObject* self)
return ConvertKeysToPython();
}
-KX_PYMETHODDEF_DOC(KX_GameObject, getDistanceTo,
+KX_PYMETHODDEF_DOC_O(KX_GameObject, getDistanceTo,
"getDistanceTo(other): get distance to another point/KX_GameObject")
{
MT_Point3 b;
- if (PyVecArgTo(args, b))
+ if (PyVecTo(value, b))
{
return PyFloat_FromDouble(NodeGetWorldPosition().distance(b));
}
PyErr_Clear();
- PyObject *pyother;
KX_GameObject *other;
- if (PyArg_ParseTuple(args, "O", &pyother) && ConvertPythonToGameObject(pyother, &other, false))
+ if (ConvertPythonToGameObject(value, &other, false))
{
return PyFloat_FromDouble(NodeGetWorldPosition().distance(other->NodeGetWorldPosition()));
}
@@ -1791,7 +1792,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, getDistanceTo,
return NULL;
}
-KX_PYMETHODDEF_DOC(KX_GameObject, getVectTo,
+KX_PYMETHODDEF_DOC_O(KX_GameObject, getVectTo,
"getVectTo(other): get vector and the distance to another point/KX_GameObject\n"
"Returns a 3-tuple with (distance,worldVector,localVector)\n")
{
@@ -1800,14 +1801,13 @@ KX_PYMETHODDEF_DOC(KX_GameObject, getVectTo,
MT_Scalar distance;
PyObject *returnValue;
- PyObject *pyother;
- if (!PyVecArgTo(args, toPoint))
+ if (!PyVecTo(value, toPoint))
{
PyErr_Clear();
KX_GameObject *other;
- if (PyArg_ParseTuple(args, "O", &pyother) && ConvertPythonToGameObject(pyother, &other, false))
+ if (ConvertPythonToGameObject(value, &other, false))
{
toPoint = other->NodeGetWorldPosition();
} else
@@ -1892,7 +1892,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
float dist = 0.0f;
char *propName = NULL;
- if (!PyArg_ParseTuple(args,"O|fs", &pyarg, &dist, &propName)) {
+ if (!PyArg_ParseTuple(args,"O|fs:rayCastTo", &pyarg, &dist, &propName)) {
return NULL; // python sets simple error
}
@@ -1935,10 +1935,8 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCastTo,
KX_RayCast::RayTest(pe, fromPoint, toPoint, callback);
if (m_pHitObject)
- {
- m_pHitObject->AddRef();
- return m_pHitObject;
- }
+ return m_pHitObject->AddRef();
+
Py_RETURN_NONE;
}
@@ -1971,7 +1969,7 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
KX_GameObject *other;
int face=0, xray=0, poly=0;
- if (!PyArg_ParseTuple(args,"O|Ofsiii", &pyto, &pyfrom, &dist, &propName, &face, &xray, &poly)) {
+ if (!PyArg_ParseTuple(args,"O|Ofsiii:rayCast", &pyto, &pyfrom, &dist, &propName, &face, &xray, &poly)) {
return NULL; // Python sets a simple error
}
@@ -2047,8 +2045,8 @@ KX_PYMETHODDEF_DOC(KX_GameObject, rayCast,
if (callback.m_hitMesh)
{
// if this field is set, then we can trust that m_hitPolygon is a valid polygon
- RAS_Polygon* poly = callback.m_hitMesh->GetPolygon(callback.m_hitPolygon);
- KX_PolyProxy* polyproxy = new KX_PolyProxy(callback.m_hitMesh, poly);
+ RAS_Polygon* polygon = callback.m_hitMesh->GetPolygon(callback.m_hitPolygon);
+ KX_PolyProxy* polyproxy = new KX_PolyProxy(callback.m_hitMesh, polygon);
PyTuple_SET_ITEM(returnValue, 3, polyproxy);
}
else
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 4f26031356f..211c9b7ca7d 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -756,19 +756,10 @@ public:
* @section Python interface functions.
*/
- virtual
- PyObject*
- _getattr(
- const STR_String& attr
- );
-
- virtual
- int
- _setattr(
- const STR_String& attr,
- PyObject *value
- ); // _setattr method
-
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value); // _setattr method
+ virtual PyObject* _repr(void) { return PyString_FromString(GetName().ReadPtr()); }
+
KX_PYMETHOD_NOARGS(KX_GameObject,GetPosition);
KX_PYMETHOD_O(KX_GameObject,SetPosition);
KX_PYMETHOD_O(KX_GameObject,SetWorldPosition);
@@ -809,8 +800,8 @@ public:
KX_PYMETHOD_NOARGS(KX_GameObject,EndObject);
KX_PYMETHOD_DOC(KX_GameObject,rayCastTo);
KX_PYMETHOD_DOC(KX_GameObject,rayCast);
- KX_PYMETHOD_DOC(KX_GameObject,getDistanceTo);
- KX_PYMETHOD_DOC(KX_GameObject,getVectTo);
+ KX_PYMETHOD_DOC_O(KX_GameObject,getDistanceTo);
+ KX_PYMETHOD_DOC_O(KX_GameObject,getVectTo);
private :
diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.cpp b/source/gameengine/Ketsji/KX_IPO_SGController.cpp
index 67d54cf0b0b..55a7e2ade60 100644
--- a/source/gameengine/Ketsji/KX_IPO_SGController.cpp
+++ b/source/gameengine/Ketsji/KX_IPO_SGController.cpp
@@ -58,8 +58,8 @@ KX_IpoSGController::KX_IpoSGController()
m_ipo_add(false),
m_ipo_local(false),
m_modified(true),
- m_ipo_start_initialized(false),
m_ipotime(1.0),
+ m_ipo_start_initialized(false),
m_ipo_start_euler(0.0,0.0,0.0),
m_ipo_euler_initialized(false)
{
diff --git a/source/gameengine/Ketsji/KX_IpoActuator.cpp b/source/gameengine/Ketsji/KX_IpoActuator.cpp
index f5e17118ffb..623a939bf62 100644
--- a/source/gameengine/Ketsji/KX_IpoActuator.cpp
+++ b/source/gameengine/Ketsji/KX_IpoActuator.cpp
@@ -457,7 +457,11 @@ PyMethodDef KX_IpoActuator::Methods[] = {
{NULL,NULL} //Sentinel
};
-PyObject* KX_IpoActuator::_getattr(const STR_String& attr) {
+PyAttributeDef KX_IpoActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* KX_IpoActuator::_getattr(const char *attr) {
_getattr_up(SCA_IActuator);
}
@@ -503,7 +507,7 @@ PyObject* KX_IpoActuator::PySet(PyObject* self,
; /* error */
}
- Py_Return;
+ Py_RETURN_NONE;
}
/* set property ----------------------------------------------------------- */
@@ -523,7 +527,7 @@ PyObject* KX_IpoActuator::PySetProperty(PyObject* self,
m_propname = propertyName;
- Py_Return;
+ Py_RETURN_NONE;
}
/* 4. setStart: */
@@ -541,7 +545,7 @@ PyObject* KX_IpoActuator::PySetStart(PyObject* self,
m_startframe = startArg;
- Py_Return;
+ Py_RETURN_NONE;
}
/* 5. getStart: */
const char KX_IpoActuator::GetStart_doc[] =
@@ -566,7 +570,7 @@ PyObject* KX_IpoActuator::PySetEnd(PyObject* self,
m_endframe = endArg;
- Py_Return;
+ Py_RETURN_NONE;
}
/* 7. getEnd: */
const char KX_IpoActuator::GetEnd_doc[] =
@@ -594,7 +598,7 @@ PyObject* KX_IpoActuator::PySetIpoAsForce(PyObject* self,
if (m_ipo_as_force)
m_ipo_add = false;
- Py_Return;
+ Py_RETURN_NONE;
}
/* 7. getIpoAsForce: */
const char KX_IpoActuator::GetIpoAsForce_doc[] =
@@ -622,7 +626,7 @@ PyObject* KX_IpoActuator::PySetIpoAdd(PyObject* self,
if (m_ipo_add)
m_ipo_as_force = false;
- Py_Return;
+ Py_RETURN_NONE;
}
/* 7. getIpoAsForce: */
const char KX_IpoActuator::GetIpoAdd_doc[] =
@@ -651,7 +655,7 @@ PyObject* KX_IpoActuator::PySetType(PyObject* self,
m_type = (IpoActType) typeArg;
}
- Py_Return;
+ Py_RETURN_NONE;
}
/* 9. getType: */
const char KX_IpoActuator::GetType_doc[] =
@@ -679,7 +683,7 @@ PyObject* KX_IpoActuator::PySetForceIpoActsLocal(PyObject* self,
m_ipo_local = PyArgToBool(boolArg);
- Py_Return;
+ Py_RETURN_NONE;
}
/* 11. getForceIpoActsLocal: */
const char KX_IpoActuator::GetForceIpoActsLocal_doc[] =
diff --git a/source/gameengine/Ketsji/KX_IpoActuator.h b/source/gameengine/Ketsji/KX_IpoActuator.h
index 8e5baed0530..12e1835ab49 100644
--- a/source/gameengine/Ketsji/KX_IpoActuator.h
+++ b/source/gameengine/Ketsji/KX_IpoActuator.h
@@ -141,7 +141,7 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
//KX_PYMETHOD_DOC
KX_PYMETHOD_DOC(KX_IpoActuator,Set);
KX_PYMETHOD_DOC(KX_IpoActuator,SetProperty);
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 1271474802c..97b4213b8bd 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -59,7 +59,10 @@
#include "KX_PythonInit.h"
#include "KX_PyConstraintBinding.h"
#include "PHY_IPhysicsEnvironment.h"
+
+#ifdef USE_SUMO_SOLID
#include "SumoPhysicsEnvironment.h"
+#endif
#include "SND_Scene.h"
#include "SND_IAudioDevice.h"
@@ -713,7 +716,7 @@ void KX_KetsjiEngine::Render()
if (!BeginFrame())
return;
- KX_SceneList::iterator sceneit;
+
for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); sceneit++)
// for each scene, call the proceed functions
{
@@ -1109,6 +1112,11 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
+ if (scene->GetPhysicsEnvironment())
+ scene->GetPhysicsEnvironment()->debugDrawWorld();
+
+ m_rasterizer->FlushDebugLines();
+
PostRenderFrame();
}
diff --git a/source/gameengine/Ketsji/KX_Light.cpp b/source/gameengine/Ketsji/KX_Light.cpp
index e0f171e78e0..a2e93ecdd36 100644
--- a/source/gameengine/Ketsji/KX_Light.cpp
+++ b/source/gameengine/Ketsji/KX_Light.cpp
@@ -172,65 +172,59 @@ void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras)
GPU_lamp_shadow_buffer_unbind(lamp);
}
-PyObject* KX_LightObject::_getattr(const STR_String& attr)
+PyObject* KX_LightObject::_getattr(const char *attr)
{
- if (attr == "layer")
+ if (!strcmp(attr, "layer"))
return PyInt_FromLong(m_lightobj.m_layer);
- if (attr == "energy")
+ if (!strcmp(attr, "energy"))
return PyFloat_FromDouble(m_lightobj.m_energy);
- if (attr == "distance")
+ if (!strcmp(attr, "distance"))
return PyFloat_FromDouble(m_lightobj.m_distance);
- if (attr == "colour" || attr == "color")
+ if (!strcmp(attr, "colour") || !strcmp(attr, "color"))
return Py_BuildValue("[fff]", m_lightobj.m_red, m_lightobj.m_green, m_lightobj.m_blue);
- if (attr == "lin_attenuation")
+ if (!strcmp(attr, "lin_attenuation"))
return PyFloat_FromDouble(m_lightobj.m_att1);
- if (attr == "quad_attenuation")
+ if (!strcmp(attr, "quad_attenuation"))
return PyFloat_FromDouble(m_lightobj.m_att2);
- if (attr == "spotsize")
+ if (!strcmp(attr, "spotsize"))
return PyFloat_FromDouble(m_lightobj.m_spotsize);
- if (attr == "spotblend")
+ if (!strcmp(attr, "spotblend"))
return PyFloat_FromDouble(m_lightobj.m_spotblend);
- if (attr == "SPOT")
+ if (!strcmp(attr, "SPOT"))
return PyInt_FromLong(RAS_LightObject::LIGHT_SPOT);
- if (attr == "SUN")
+ if (!strcmp(attr, "SUN"))
return PyInt_FromLong(RAS_LightObject::LIGHT_SUN);
- if (attr == "NORMAL")
+ if (!strcmp(attr, "NORMAL"))
return PyInt_FromLong(RAS_LightObject::LIGHT_NORMAL);
- if (attr == "type")
+ if (!strcmp(attr, "type"))
return PyInt_FromLong(m_lightobj.m_type);
_getattr_up(KX_GameObject);
}
-int KX_LightObject::_setattr(const STR_String& attr, PyObject *pyvalue)
-{
- if (attr == "SPOT" || attr == "SUN" || attr == "NORMAL")
- {
- PyErr_Format(PyExc_RuntimeError, "Attribute %s is read only.", attr.ReadPtr());
- return 1;
- }
-
+int KX_LightObject::_setattr(const char *attr, PyObject *pyvalue)
+{
if (PyInt_Check(pyvalue))
{
int value = PyInt_AsLong(pyvalue);
- if (attr == "layer")
+ if (!strcmp(attr, "layer"))
{
m_lightobj.m_layer = value;
return 0;
}
- if (attr == "type")
+ if (!strcmp(attr, "type"))
{
if (value >= RAS_LightObject::LIGHT_SPOT && value <= RAS_LightObject::LIGHT_NORMAL)
m_lightobj.m_type = (RAS_LightObject::LightType) value;
@@ -241,37 +235,37 @@ int KX_LightObject::_setattr(const STR_String& attr, PyObject *pyvalue)
if (PyFloat_Check(pyvalue))
{
float value = PyFloat_AsDouble(pyvalue);
- if (attr == "energy")
+ if (!strcmp(attr, "energy"))
{
m_lightobj.m_energy = value;
return 0;
}
- if (attr == "distance")
+ if (!strcmp(attr, "distance"))
{
m_lightobj.m_distance = value;
return 0;
}
- if (attr == "lin_attenuation")
+ if (!strcmp(attr, "lin_attenuation"))
{
m_lightobj.m_att1 = value;
return 0;
}
- if (attr == "quad_attenuation")
+ if (!strcmp(attr, "quad_attenuation"))
{
m_lightobj.m_att2 = value;
return 0;
}
- if (attr == "spotsize")
+ if (!strcmp(attr, "spotsize"))
{
m_lightobj.m_spotsize = value;
return 0;
}
- if (attr == "spotblend")
+ if (!strcmp(attr, "spotblend"))
{
m_lightobj.m_spotblend = value;
return 0;
@@ -280,7 +274,7 @@ int KX_LightObject::_setattr(const STR_String& attr, PyObject *pyvalue)
if (PySequence_Check(pyvalue))
{
- if (attr == "colour" || attr == "color")
+ if (!strcmp(attr, "colour") || !strcmp(attr, "color"))
{
MT_Vector3 color;
if (PyVecTo(pyvalue, color))
@@ -294,6 +288,12 @@ int KX_LightObject::_setattr(const STR_String& attr, PyObject *pyvalue)
}
}
+ if (!strcmp(attr, "SPOT") || !strcmp(attr, "SUN") || !strcmp(attr, "NORMAL"))
+ {
+ PyErr_Format(PyExc_RuntimeError, "Attribute %s is read only.", attr);
+ return 1;
+ }
+
return KX_GameObject::_setattr(attr, pyvalue);
}
@@ -301,6 +301,10 @@ PyMethodDef KX_LightObject::Methods[] = {
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_LightObject::Attributes[] = {
+ { NULL } //Sentinel
+};
+
char KX_LightObject::doc[] = "Module KX_LightObject\n\n"
"Constants:\n"
"\tSPOT\n"
diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h
index e5dbf0b7f4a..47edd09b5b9 100644
--- a/source/gameengine/Ketsji/KX_Light.h
+++ b/source/gameengine/Ketsji/KX_Light.h
@@ -63,8 +63,8 @@ public:
void UnbindShadowBuffer(class RAS_IRasterizer *ras);
void Update();
- virtual PyObject* _getattr(const STR_String& attr); /* lens, near, far, projection_matrix */
- virtual int _setattr(const STR_String& attr, PyObject *pyvalue);
+ virtual PyObject* _getattr(const char *attr); /* lens, near, far, projection_matrix */
+ virtual int _setattr(const char *attr, PyObject *pyvalue);
virtual bool IsLight(void) { return true; }
};
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp
index 5cc102248f2..a0c0a496c06 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.cpp
+++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp
@@ -86,6 +86,10 @@ KX_PYMETHODTABLE(KX_MeshProxy, reinstancePhysicsMesh),
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_MeshProxy::Attributes[] = {
+ { NULL } //Sentinel
+};
+
void KX_MeshProxy::SetMeshModified(bool v)
{
m_meshobj->SetMeshModified(v);
@@ -93,9 +97,9 @@ void KX_MeshProxy::SetMeshModified(bool v)
PyObject*
-KX_MeshProxy::_getattr(const STR_String& attr)
+KX_MeshProxy::_getattr(const char *attr)
{
- if (attr == "materials")
+ if (!strcmp(attr, "materials"))
{
PyObject *materials = PyList_New(0);
list<RAS_MeshMaterial>::iterator mit = m_meshobj->GetFirstMaterial();
diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h
index 3335c349673..34f60a54a3a 100644
--- a/source/gameengine/Ketsji/KX_MeshProxy.h
+++ b/source/gameengine/Ketsji/KX_MeshProxy.h
@@ -53,7 +53,7 @@ public:
virtual CValue* GetReplica();
// stuff for python integration
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
KX_PYMETHOD(KX_MeshProxy,GetNumMaterials);
KX_PYMETHOD(KX_MeshProxy,GetMaterialName);
KX_PYMETHOD(KX_MeshProxy,GetTextureName);
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
index 28279b9a6b8..384034485e7 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
@@ -42,6 +42,7 @@
#include "KX_Scene.h"
#include "KX_Camera.h"
#include "KX_MouseFocusSensor.h"
+#include "KX_PyMath.h"
#include "KX_RayCast.h"
#include "KX_IPhysicsController.h"
@@ -320,18 +321,22 @@ PyParentObject KX_MouseFocusSensor::Parents[] = {
};
PyMethodDef KX_MouseFocusSensor::Methods[] = {
- {"getRayTarget", (PyCFunction) KX_MouseFocusSensor::sPyGetRayTarget, METH_VARARGS, (PY_METHODCHAR)GetRayTarget_doc},
- {"getRaySource", (PyCFunction) KX_MouseFocusSensor::sPyGetRaySource, METH_VARARGS, (PY_METHODCHAR)GetRaySource_doc},
- {"getHitObject",(PyCFunction) KX_MouseFocusSensor::sPyGetHitObject,METH_VARARGS, (PY_METHODCHAR)GetHitObject_doc},
- {"getHitPosition",(PyCFunction) KX_MouseFocusSensor::sPyGetHitPosition,METH_VARARGS, (PY_METHODCHAR)GetHitPosition_doc},
- {"getHitNormal",(PyCFunction) KX_MouseFocusSensor::sPyGetHitNormal,METH_VARARGS, (PY_METHODCHAR)GetHitNormal_doc},
- {"getRayDirection",(PyCFunction) KX_MouseFocusSensor::sPyGetRayDirection,METH_VARARGS, (PY_METHODCHAR)GetRayDirection_doc},
+ {"getRayTarget", (PyCFunction) KX_MouseFocusSensor::sPyGetRayTarget, METH_NOARGS, (PY_METHODCHAR)GetRayTarget_doc},
+ {"getRaySource", (PyCFunction) KX_MouseFocusSensor::sPyGetRaySource, METH_NOARGS, (PY_METHODCHAR)GetRaySource_doc},
+ {"getHitObject",(PyCFunction) KX_MouseFocusSensor::sPyGetHitObject,METH_NOARGS, (PY_METHODCHAR)GetHitObject_doc},
+ {"getHitPosition",(PyCFunction) KX_MouseFocusSensor::sPyGetHitPosition,METH_NOARGS, (PY_METHODCHAR)GetHitPosition_doc},
+ {"getHitNormal",(PyCFunction) KX_MouseFocusSensor::sPyGetHitNormal,METH_NOARGS, (PY_METHODCHAR)GetHitNormal_doc},
+ {"getRayDirection",(PyCFunction) KX_MouseFocusSensor::sPyGetRayDirection,METH_NOARGS, (PY_METHODCHAR)GetRayDirection_doc},
{NULL,NULL} //Sentinel
};
-PyObject* KX_MouseFocusSensor::_getattr(const STR_String& attr) {
+PyAttributeDef KX_MouseFocusSensor::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* KX_MouseFocusSensor::_getattr(const char *attr) {
_getattr_up(SCA_MouseSensor);
}
@@ -339,76 +344,40 @@ PyObject* KX_MouseFocusSensor::_getattr(const STR_String& attr) {
const char KX_MouseFocusSensor::GetHitObject_doc[] =
"getHitObject()\n"
"\tReturns the name of the object that was hit by this ray.\n";
-PyObject* KX_MouseFocusSensor::PyGetHitObject(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_MouseFocusSensor::PyGetHitObject(PyObject* self)
{
if (m_hitObject)
- {
return m_hitObject->AddRef();
- }
- Py_Return;
+
+ Py_RETURN_NONE;
}
const char KX_MouseFocusSensor::GetHitPosition_doc[] =
"getHitPosition()\n"
"\tReturns the position (in worldcoordinates) where the object was hit by this ray.\n";
-PyObject* KX_MouseFocusSensor::PyGetHitPosition(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_MouseFocusSensor::PyGetHitPosition(PyObject* self)
{
-
- MT_Point3 pos = m_hitPosition;
-
- PyObject* resultlist = PyList_New(3);
- int index;
- for (index=0;index<3;index++)
- {
- PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index]));
- }
- return resultlist;
-
+ return PyObjectFrom(m_hitPosition);
}
const char KX_MouseFocusSensor::GetRayDirection_doc[] =
"getRayDirection()\n"
"\tReturns the direction from the ray (in worldcoordinates) .\n";
-PyObject* KX_MouseFocusSensor::PyGetRayDirection(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_MouseFocusSensor::PyGetRayDirection(PyObject* self)
{
MT_Vector3 dir = m_prevTargetPoint - m_prevSourcePoint;
dir.normalize();
-
- PyObject* resultlist = PyList_New(3);
- int index;
- for (index=0;index<3;index++)
- {
- PyList_SetItem(resultlist,index,PyFloat_FromDouble(dir[index]));
- }
- return resultlist;
-
+ return PyObjectFrom(dir);
}
const char KX_MouseFocusSensor::GetHitNormal_doc[] =
"getHitNormal()\n"
"\tReturns the normal (in worldcoordinates) of the object at the location where the object was hit by this ray.\n";
-PyObject* KX_MouseFocusSensor::PyGetHitNormal(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_MouseFocusSensor::PyGetHitNormal(PyObject* self)
{
- MT_Vector3 pos = m_hitNormal;
-
- PyObject* resultlist = PyList_New(3);
- int index;
- for (index=0;index<3;index++)
- {
- PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index]));
- }
- return resultlist;
-
+ return PyObjectFrom(m_hitNormal);
}
@@ -417,16 +386,8 @@ const char KX_MouseFocusSensor::GetRayTarget_doc[] =
"getRayTarget()\n"
"\tReturns the target of the ray that seeks the focus object,\n"
"\tin worldcoordinates.";
-PyObject* KX_MouseFocusSensor::PyGetRayTarget(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
- PyObject *retVal = PyList_New(3);
-
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_prevTargetPoint[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_prevTargetPoint[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_prevTargetPoint[2]));
-
- return retVal;
+PyObject* KX_MouseFocusSensor::PyGetRayTarget(PyObject* self) {
+ return PyObjectFrom(m_prevTargetPoint);
}
/* getRayTarget */
@@ -434,16 +395,8 @@ const char KX_MouseFocusSensor::GetRaySource_doc[] =
"getRaySource()\n"
"\tReturns the source of the ray that seeks the focus object,\n"
"\tin worldcoordinates.";
-PyObject* KX_MouseFocusSensor::PyGetRaySource(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
- PyObject *retVal = PyList_New(3);
-
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_prevSourcePoint[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_prevSourcePoint[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_prevSourcePoint[2]));
-
- return retVal;
+PyObject* KX_MouseFocusSensor::PyGetRaySource(PyObject* self) {
+ return PyObjectFrom(m_prevSourcePoint);
}
/* eof */
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
index 6731444699b..4979783032c 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
@@ -87,15 +87,15 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
- KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetRayTarget);
- KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetRaySource);
+ KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetRayTarget);
+ KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetRaySource);
- KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetHitObject);
- KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetHitPosition);
- KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetHitNormal);
- KX_PYMETHOD_DOC(KX_MouseFocusSensor,GetRayDirection);
+ KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetHitObject);
+ KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetHitPosition);
+ KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetHitNormal);
+ KX_PYMETHOD_DOC_NOARGS(KX_MouseFocusSensor,GetRayDirection);
/* --------------------------------------------------------------------- */
SCA_IObject* m_hitObject;
diff --git a/source/gameengine/Ketsji/KX_NearSensor.cpp b/source/gameengine/Ketsji/KX_NearSensor.cpp
index bae87c28123..993a6b3d86c 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.cpp
+++ b/source/gameengine/Ketsji/KX_NearSensor.cpp
@@ -37,14 +37,13 @@
#include "PHY_IPhysicsEnvironment.h"
#include "PHY_IPhysicsController.h"
-
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr,
KX_GameObject* gameobj,
- double margin,
- double resetmargin,
+ float margin,
+ float resetmargin,
bool bFindMaterial,
const STR_String& touchedpropname,
class KX_Scene* scene,
@@ -53,6 +52,7 @@ KX_NearSensor::KX_NearSensor(SCA_EventManager* eventmgr,
:KX_TouchSensor(eventmgr,
gameobj,
bFindMaterial,
+ false,
touchedpropname,
/* scene, */
T),
@@ -240,7 +240,7 @@ bool KX_NearSensor::BroadPhaseFilterCollision(void*obj1,void*obj2)
bool KX_NearSensor::NewHandleCollision(void* obj1,void* obj2,const PHY_CollData * coll_data)
{
// KX_TouchEventManager* toucheventmgr = static_cast<KX_TouchEventManager*>(m_eventmgr);
- KX_GameObject* parent = static_cast<KX_GameObject*>(GetParent());
+// KX_GameObject* parent = static_cast<KX_GameObject*>(GetParent());
// need the mapping from PHY_IPhysicsController to gameobjects now
@@ -272,12 +272,20 @@ bool KX_NearSensor::NewHandleCollision(void* obj1,void* obj2,const PHY_CollData
//}
}
- return DT_CONTINUE;
+ return false; // was DT_CONTINUE; but this was defined in Sumo as false
}
+/* ------------------------------------------------------------------------- */
+/* Python Functions */
+/* ------------------------------------------------------------------------- */
+
+//No methods
+
+/* ------------------------------------------------------------------------- */
+/* Python Integration Hooks */
+/* ------------------------------------------------------------------------- */
-// python embedding
PyTypeObject KX_NearSensor::Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
@@ -311,17 +319,31 @@ PyParentObject KX_NearSensor::Parents[] = {
PyMethodDef KX_NearSensor::Methods[] = {
- {"setProperty", (PyCFunction) KX_NearSensor::sPySetProperty, METH_VARARGS, (PY_METHODCHAR)SetProperty_doc},
- {"getProperty", (PyCFunction) KX_NearSensor::sPyGetProperty, METH_VARARGS, (PY_METHODCHAR)GetProperty_doc},
- {"getHitObject",(PyCFunction) KX_NearSensor::sPyGetHitObject, METH_VARARGS, (PY_METHODCHAR)GetHitObject_doc},
- {"getHitObjectList", (PyCFunction) KX_NearSensor::sPyGetHitObjectList, METH_VARARGS, (PY_METHODCHAR)GetHitObjectList_doc},
+ //No methods
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_NearSensor::Attributes[] = {
+ KX_PYATTRIBUTE_FLOAT_RW_CHECK("distance", 0, 100, KX_NearSensor, m_Margin, CheckResetDistance),
+ KX_PYATTRIBUTE_FLOAT_RW_CHECK("resetDistance", 0, 100, KX_NearSensor, m_ResetMargin, CheckResetDistance),
+ {NULL} //Sentinel
+};
-PyObject*
-KX_NearSensor::_getattr(const STR_String& attr)
+
+PyObject* KX_NearSensor::_getattr(const char *attr)
{
- _getattr_up(KX_TouchSensor);
+ PyObject* object = _getattr_self(Attributes, this, attr);
+ if (object != NULL)
+ return object;
+
+ _getattr_up(KX_TouchSensor);
}
+int KX_NearSensor::_setattr(const char *attr, PyObject* value)
+{
+ int ret = _setattr_self(Attributes, this, attr, value);
+ if (ret >= 0)
+ return ret;
+
+ return KX_TouchSensor::_setattr(attr, value);
+}
diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h
index 3f7078ef9fd..ee03992e734 100644
--- a/source/gameengine/Ketsji/KX_NearSensor.h
+++ b/source/gameengine/Ketsji/KX_NearSensor.h
@@ -42,15 +42,15 @@ class KX_NearSensor : public KX_TouchSensor
{
Py_Header;
protected:
- double m_Margin;
- double m_ResetMargin;
+ float m_Margin;
+ float m_ResetMargin;
KX_Scene* m_scene;
KX_ClientObjectInfo* m_client_info;
public:
KX_NearSensor(class SCA_EventManager* eventmgr,
class KX_GameObject* gameobj,
- double margin,
- double resetmargin,
+ float margin,
+ float resetmargin,
bool bFindMaterial,
const STR_String& touchedpropname,
class KX_Scene* scene,
@@ -78,8 +78,25 @@ public:
virtual bool BroadPhaseFilterCollision(void*obj1,void*obj2);
virtual void RegisterSumo(KX_TouchEventManager *touchman);
virtual void UnregisterSumo(KX_TouchEventManager* touchman);
-
- virtual PyObject* _getattr(const STR_String& attr);
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject* value);
+
+ //No methods
+
+ //This method is used to make sure the distance does not exceed the reset distance
+ static int CheckResetDistance(void *self, const PyAttributeDef*)
+ {
+ KX_NearSensor* sensor = reinterpret_cast<KX_NearSensor*>(self);
+
+ if (sensor->m_Margin > sensor->m_ResetMargin)
+ sensor->m_ResetMargin = sensor->m_Margin;
+
+ return 0;
+ }
};
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
index 98e73d4f0d7..0666261b470 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp
@@ -65,12 +65,12 @@ KX_ObjectActuator(
m_current_linear_factor(0.0),
m_current_angular_factor(0.0),
m_damping(damping),
+ m_previous_error(0.0,0.0,0.0),
+ m_error_accumulator(0.0,0.0,0.0),
m_bitLocalFlag (flag),
m_active_combined_velocity (false),
m_linear_damping_active(false),
- m_angular_damping_active(false),
- m_error_accumulator(0.0,0.0,0.0),
- m_previous_error(0.0,0.0,0.0)
+ m_angular_damping_active(false)
{
if (m_bitLocalFlag.ServoControl)
{
@@ -332,7 +332,11 @@ PyMethodDef KX_ObjectActuator::Methods[] = {
{NULL,NULL} //Sentinel
};
-PyObject* KX_ObjectActuator::_getattr(const STR_String& attr) {
+PyAttributeDef KX_ObjectActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* KX_ObjectActuator::_getattr(const char *attr) {
_getattr_up(SCA_IActuator);
};
@@ -365,7 +369,7 @@ PyObject* KX_ObjectActuator::PySetForce(PyObject* self,
m_force.setValue(vecArg);
m_bitLocalFlag.Force = PyArgToBool(bToggle);
UpdateFuzzyFlags();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 4. getTorque */
@@ -394,7 +398,7 @@ PyObject* KX_ObjectActuator::PySetTorque(PyObject* self,
m_torque.setValue(vecArg);
m_bitLocalFlag.Torque = PyArgToBool(bToggle);
UpdateFuzzyFlags();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 6. getDLoc */
@@ -423,7 +427,7 @@ PyObject* KX_ObjectActuator::PySetDLoc(PyObject* self,
m_dloc.setValue(vecArg);
m_bitLocalFlag.DLoc = PyArgToBool(bToggle);
UpdateFuzzyFlags();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 8. getDRot */
@@ -452,7 +456,7 @@ PyObject* KX_ObjectActuator::PySetDRot(PyObject* self,
m_drot.setValue(vecArg);
m_bitLocalFlag.DRot = PyArgToBool(bToggle);
UpdateFuzzyFlags();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 10. getLinearVelocity */
@@ -480,7 +484,7 @@ PyObject* KX_ObjectActuator::PySetLinearVelocity(PyObject* self,
m_linear_velocity.setValue(vecArg);
m_bitLocalFlag.LinearVelocity = PyArgToBool(bToggle);
UpdateFuzzyFlags();
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -508,7 +512,7 @@ PyObject* KX_ObjectActuator::PySetAngularVelocity(PyObject* self,
m_angular_velocity.setValue(vecArg);
m_bitLocalFlag.AngularVelocity = PyArgToBool(bToggle);
UpdateFuzzyFlags();
- Py_Return;
+ Py_RETURN_NONE;
}
/* 13. setDamping */
@@ -520,7 +524,7 @@ PyObject* KX_ObjectActuator::PySetDamping(PyObject* self,
return NULL;
}
m_damping = damping;
- Py_Return;
+ Py_RETURN_NONE;
}
/* 13. getVelocityDamping */
@@ -551,7 +555,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitX(PyObject* self,
m_drot[0] = vecArg[0];
m_dloc[0] = vecArg[1];
m_bitLocalFlag.Torque = PyArgToBool(bToggle);
- Py_Return;
+ Py_RETURN_NONE;
}
/* 6. getForceLimitY */
@@ -578,7 +582,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitY(PyObject* self,
m_drot[1] = vecArg[0];
m_dloc[1] = vecArg[1];
m_bitLocalFlag.DLoc = PyArgToBool(bToggle);
- Py_Return;
+ Py_RETURN_NONE;
}
/* 6. getForceLimitZ */
@@ -605,7 +609,7 @@ PyObject* KX_ObjectActuator::PySetForceLimitZ(PyObject* self,
m_drot[2] = vecArg[0];
m_dloc[2] = vecArg[1];
m_bitLocalFlag.DRot = PyArgToBool(bToggle);
- Py_Return;
+ Py_RETURN_NONE;
}
/* 4. getPID */
@@ -629,7 +633,7 @@ PyObject* KX_ObjectActuator::PySetPID(PyObject* self,
return NULL;
}
m_torque.setValue(vecArg);
- Py_Return;
+ Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h
index aa686f41233..0331c67617c 100644
--- a/source/gameengine/Ketsji/KX_ObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_ObjectActuator.h
@@ -153,7 +153,7 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
KX_PYMETHOD_NOARGS(KX_ObjectActuator,GetForce);
KX_PYMETHOD(KX_ObjectActuator,SetForce);
diff --git a/source/gameengine/Ketsji/KX_ParentActuator.cpp b/source/gameengine/Ketsji/KX_ParentActuator.cpp
index 89549ca6b57..84d7ccb9c05 100644
--- a/source/gameengine/Ketsji/KX_ParentActuator.cpp
+++ b/source/gameengine/Ketsji/KX_ParentActuator.cpp
@@ -166,15 +166,48 @@ PyParentObject KX_ParentActuator::Parents[] = {
};
PyMethodDef KX_ParentActuator::Methods[] = {
+ // ---> deprecated (all)
{"setObject", (PyCFunction) KX_ParentActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc},
{"getObject", (PyCFunction) KX_ParentActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc},
{NULL,NULL} //Sentinel
};
-PyObject* KX_ParentActuator::_getattr(const STR_String& attr) {
+PyAttributeDef KX_ParentActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* KX_ParentActuator::_getattr(const char *attr) {
+
+ if (!strcmp(attr, "object")) {
+ if (!m_ob) Py_RETURN_NONE;
+ else return m_ob->AddRef();
+ }
+
_getattr_up(SCA_IActuator);
}
+int KX_ParentActuator::_setattr(const char *attr, PyObject* value) {
+
+ if (!strcmp(attr, "object")) {
+ KX_GameObject *gameobj;
+
+ if (!ConvertPythonToGameObject(value, &gameobj, true))
+ return 1; // ConvertPythonToGameObject sets the error
+
+ if (m_ob != NULL)
+ m_ob->UnregisterActuator(this);
+
+ m_ob = (SCA_IObject*)gameobj;
+
+ if (m_ob)
+ m_ob->RegisterActuator(this);
+
+ return 0;
+ }
+
+ return SCA_IActuator::_setattr(attr, value);
+}
+
/* 1. setObject */
const char KX_ParentActuator::SetObject_doc[] =
"setObject(object)\n"
@@ -183,6 +216,8 @@ const char KX_ParentActuator::SetObject_doc[] =
PyObject* KX_ParentActuator::PySetObject(PyObject* self, PyObject* value) {
KX_GameObject *gameobj;
+ ShowDeprecationWarning("setObject()", "the object property");
+
if (!ConvertPythonToGameObject(value, &gameobj, true))
return NULL; // ConvertPythonToGameObject sets the error
@@ -206,6 +241,9 @@ const char KX_ParentActuator::GetObject_doc[] =
PyObject* KX_ParentActuator::PyGetObject(PyObject* self, PyObject* args)
{
int ret_name_only = 1;
+
+ ShowDeprecationWarning("getObject()", "the object property");
+
if (!PyArg_ParseTuple(args, "|i", &ret_name_only))
return NULL;
diff --git a/source/gameengine/Ketsji/KX_ParentActuator.h b/source/gameengine/Ketsji/KX_ParentActuator.h
index e2b30ba2d0f..c974001c0d0 100644
--- a/source/gameengine/Ketsji/KX_ParentActuator.h
+++ b/source/gameengine/Ketsji/KX_ParentActuator.h
@@ -76,7 +76,8 @@ class KX_ParentActuator : public SCA_IActuator
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject* value);
/* 1. setObject */
KX_PYMETHOD_DOC_O(KX_ParentActuator,SetObject);
diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
index da4f05ced7c..246c63feb21 100644
--- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.cpp
@@ -142,23 +142,21 @@ PyParentObject KX_PhysicsObjectWrapper::Parents[] = {
NULL
};
-PyObject* KX_PhysicsObjectWrapper::_getattr(const STR_String& attr)
+PyObject* KX_PhysicsObjectWrapper::_getattr(const char *attr)
{
_getattr_up(PyObjectPlus);
}
-int KX_PhysicsObjectWrapper::_setattr(const STR_String& attr,PyObject* pyobj)
+int KX_PhysicsObjectWrapper::_setattr(const char *attr,PyObject *pyobj)
{
- PyTypeObject* type = pyobj->ob_type;
int result = 1;
-
- if (type == &PyInt_Type)
+ if (PyInt_Check(pyobj))
{
result = 0;
}
- if (type == &PyString_Type)
+ if (PyString_Check(pyobj))
{
result = 0;
}
diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h
index 3dbd1be9323..95560698896 100644
--- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h
+++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h
@@ -36,8 +36,8 @@ class KX_PhysicsObjectWrapper : public PyObjectPlus
{
Py_Header;
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
public:
KX_PhysicsObjectWrapper(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsEnvironment* physenv,PyTypeObject *T = &Type);
virtual ~KX_PhysicsObjectWrapper();
diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp
index bb9072b34dc..b4bdd77fb66 100644
--- a/source/gameengine/Ketsji/KX_PolyProxy.cpp
+++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp
@@ -77,18 +77,21 @@ PyMethodDef KX_PolyProxy::Methods[] = {
{NULL,NULL} //Sentinel
};
-PyObject*
-KX_PolyProxy::_getattr(const STR_String& attr)
+PyAttributeDef KX_PolyProxy::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* KX_PolyProxy::_getattr(const char *attr)
{
- if (attr == "matname")
+ if (!strcmp(attr, "matname"))
{
return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName());
}
- if (attr == "texture")
+ if (!strcmp(attr, "texture"))
{
return PyString_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName());
}
- if (attr == "material")
+ if (!strcmp(attr, "material"))
{
RAS_IPolyMaterial *polymat = m_polygon->GetMaterial()->GetPolyMaterial();
if(polymat->GetFlag() & RAS_BLENDERMAT)
@@ -104,7 +107,7 @@ KX_PolyProxy::_getattr(const STR_String& attr)
return mat;
}
}
- if (attr == "matid")
+ if (!strcmp(attr, "matid"))
{
// we'll have to scan through the material bucket of the mes and compare with
// the one of the polygon
@@ -119,27 +122,27 @@ KX_PolyProxy::_getattr(const STR_String& attr)
}
return PyInt_FromLong(matid);
}
- if (attr == "v1")
+ if (!strcmp(attr, "v1"))
{
return PyInt_FromLong(m_polygon->GetVertexOffset(0));
}
- if (attr == "v2")
+ if (!strcmp(attr, "v2"))
{
return PyInt_FromLong(m_polygon->GetVertexOffset(1));
}
- if (attr == "v3")
+ if (!strcmp(attr, "v3"))
{
return PyInt_FromLong(m_polygon->GetVertexOffset(2));
}
- if (attr == "v4")
+ if (!strcmp(attr, "v4"))
{
return PyInt_FromLong(((m_polygon->VertexCount()>3)?m_polygon->GetVertexOffset(3):0));
}
- if (attr == "visible")
+ if (!strcmp(attr, "visible"))
{
return PyInt_FromLong(m_polygon->IsVisible());
}
- if (attr == "collide")
+ if (!strcmp(attr, "collide"))
{
return PyInt_FromLong(m_polygon->IsCollider());
}
@@ -147,8 +150,8 @@ KX_PolyProxy::_getattr(const STR_String& attr)
}
KX_PolyProxy::KX_PolyProxy(const RAS_MeshObject*mesh, RAS_Polygon* polygon)
-: m_mesh((RAS_MeshObject*)mesh),
- m_polygon(polygon)
+: m_polygon(polygon),
+ m_mesh((RAS_MeshObject*)mesh)
{
}
diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h
index 506e2c2a656..9b548f9490d 100644
--- a/source/gameengine/Ketsji/KX_PolyProxy.h
+++ b/source/gameengine/Ketsji/KX_PolyProxy.h
@@ -53,7 +53,7 @@ public:
// stuff for python integration
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getMaterialIndex)
KX_PYMETHOD_DOC_NOARGS(KX_PolyProxy,getNumVertex)
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
index c9180bf3a80..bbaf697b168 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp
@@ -180,6 +180,9 @@ PyMethodDef KX_PolygonMaterial::Methods[] = {
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_PolygonMaterial::Attributes[] = {
+ { NULL } //Sentinel
+};
PyTypeObject KX_PolygonMaterial::Type = {
PyObject_HEAD_INIT(&PyType_Type)
@@ -202,17 +205,17 @@ PyParentObject KX_PolygonMaterial::Parents[] = {
NULL
};
-PyObject* KX_PolygonMaterial::_getattr(const STR_String& attr)
+PyObject* KX_PolygonMaterial::_getattr(const char *attr)
{
- if (attr == "texture")
+ if (!strcmp(attr, "texture"))
return PyString_FromString(m_texturename.ReadPtr());
- if (attr == "material")
+ if (!strcmp(attr, "material"))
return PyString_FromString(m_materialname.ReadPtr());
- if (attr == "tface")
+ if (!strcmp(attr, "tface"))
return PyCObject_FromVoidPtr(m_tface, NULL);
- if (attr == "gl_texture")
+ if (!strcmp(attr, "gl_texture"))
{
Image *ima = m_tface->tpage;
int bind = 0;
@@ -222,49 +225,49 @@ PyObject* KX_PolygonMaterial::_getattr(const STR_String& attr)
return PyInt_FromLong(bind);
}
- if (attr == "tile")
+ if (!strcmp(attr, "tile"))
return PyInt_FromLong(m_tile);
- if (attr == "tilexrep")
+ if (!strcmp(attr, "tilexrep"))
return PyInt_FromLong(m_tilexrep);
- if (attr == "tileyrep")
+ if (!strcmp(attr, "tileyrep"))
return PyInt_FromLong(m_tileyrep);
- if (attr == "drawingmode")
+ if (!strcmp(attr, "drawingmode"))
return PyInt_FromLong(m_drawingmode);
- if (attr == "transparent")
+ if (!strcmp(attr, "transparent"))
return PyInt_FromLong(m_alpha);
- if (attr == "zsort")
+ if (!strcmp(attr, "zsort"))
return PyInt_FromLong(m_zsort);
- if (attr == "lightlayer")
+ if (!strcmp(attr, "lightlayer"))
return PyInt_FromLong(m_lightlayer);
- if (attr == "triangle")
+ if (!strcmp(attr, "triangle"))
// deprecated, triangle/quads shouldn't have been a material property
return 0;
- if (attr == "diffuse")
+ if (!strcmp(attr, "diffuse"))
return PyObjectFrom(m_diffuse);
- if (attr == "shininess")
+ if (!strcmp(attr, "shininess"))
return PyFloat_FromDouble(m_shininess);
- if (attr == "specular")
+ if (!strcmp(attr, "specular"))
return PyObjectFrom(m_specular);
- if (attr == "specularity")
+ if (!strcmp(attr, "specularity"))
return PyFloat_FromDouble(m_specularity);
_getattr_up(PyObjectPlus);
}
-int KX_PolygonMaterial::_setattr(const STR_String &attr, PyObject *pyvalue)
+int KX_PolygonMaterial::_setattr(const char *attr, PyObject *pyvalue)
{
if (PyFloat_Check(pyvalue))
{
float value = PyFloat_AsDouble(pyvalue);
- if (attr == "shininess")
+ if (!strcmp(attr, "shininess"))
{
m_shininess = value;
return 0;
}
- if (attr == "specularity")
+ if (!strcmp(attr, "specularity"))
{
m_specularity = value;
return 0;
@@ -274,50 +277,50 @@ int KX_PolygonMaterial::_setattr(const STR_String &attr, PyObject *pyvalue)
if (PyInt_Check(pyvalue))
{
int value = PyInt_AsLong(pyvalue);
- if (attr == "tile")
+ if (!strcmp(attr, "tile"))
{
m_tile = value;
return 0;
}
- if (attr == "tilexrep")
+ if (!strcmp(attr, "tilexrep"))
{
m_tilexrep = value;
return 0;
}
- if (attr == "tileyrep")
+ if (!strcmp(attr, "tileyrep"))
{
m_tileyrep = value;
return 0;
}
- if (attr == "drawingmode")
+ if (!strcmp(attr, "drawingmode"))
{
m_drawingmode = value;
return 0;
}
- if (attr == "transparent")
+ if (!strcmp(attr, "transparent"))
{
m_alpha = value;
return 0;
}
- if (attr == "zsort")
+ if (!strcmp(attr, "zsort"))
{
m_zsort = value;
return 0;
}
- if (attr == "lightlayer")
+ if (!strcmp(attr, "lightlayer"))
{
m_lightlayer = value;
return 0;
}
// This probably won't work...
- if (attr == "triangle")
+ if (!strcmp(attr, "triangle"))
{
// deprecated, triangle/quads shouldn't have been a material property
return 0;
@@ -331,13 +334,13 @@ int KX_PolygonMaterial::_setattr(const STR_String &attr, PyObject *pyvalue)
MT_Vector3 value;
if (PyVecTo(pyvalue, value))
{
- if (attr == "diffuse")
+ if (!strcmp(attr, "diffuse"))
{
m_diffuse = value;
return 0;
}
- if (attr == "specular")
+ if (!strcmp(attr, "specular"))
{
m_specular = value;
return 0;
@@ -354,12 +357,12 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setCustomMaterial, "setCustomMaterial(mat
PyObject *material;
if (PyArg_ParseTuple(args, "O", &material))
{
- if (m_pymaterial)
+ if (m_pymaterial) {
Py_DECREF(m_pymaterial);
-
+ }
m_pymaterial = material;
Py_INCREF(m_pymaterial);
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
@@ -375,7 +378,7 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, updateTexture, "updateTexture(tface, rast
Image *ima = (Image*)tface->tpage;
GPU_update_image_time(ima, rasty->GetTime());
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
@@ -388,7 +391,7 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setTexture, "setTexture(tface)")
{
MTFace *tface = (MTFace*) PyCObject_AsVoidPtr(pytface);
GPU_set_tpage(tface);
- Py_Return;
+ Py_RETURN_NONE;
}
return NULL;
@@ -404,7 +407,7 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, activate, "activate(rasty, cachingInfo)")
if (rasty && cachingInfo)
{
DefaultActivate(rasty, *cachingInfo);
- Py_Return;
+ Py_RETURN_NONE;
}
}
diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h
index fe116f757db..a3ef4ca51ef 100644
--- a/source/gameengine/Ketsji/KX_PolygonMaterial.h
+++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h
@@ -115,8 +115,8 @@ public:
KX_PYMETHOD_DOC(KX_PolygonMaterial, setCustomMaterial);
KX_PYMETHOD_DOC(KX_PolygonMaterial, loadProgram);
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *pyvalue);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *pyvalue);
};
#endif // __KX_POLYGONMATERIAL_H__
diff --git a/source/gameengine/Ketsji/KX_PyMath.cpp b/source/gameengine/Ketsji/KX_PyMath.cpp
index afb20acec2d..92f18590a7e 100644
--- a/source/gameengine/Ketsji/KX_PyMath.cpp
+++ b/source/gameengine/Ketsji/KX_PyMath.cpp
@@ -77,35 +77,92 @@ bool PyObject_IsMT_Matrix(PyObject *pymat, unsigned int rank)
PyObject* PyObjectFrom(const MT_Matrix4x4 &mat)
{
+#if 0
return Py_BuildValue("[[ffff][ffff][ffff][ffff]]",
mat[0][0], mat[0][1], mat[0][2], mat[0][3],
mat[1][0], mat[1][1], mat[1][2], mat[1][3],
mat[2][0], mat[2][1], mat[2][2], mat[2][3],
mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
+#else
+ PyObject *list = PyList_New(4);
+ PyObject *sublist;
+ int i;
+
+ for(i=0; i < 4; i++) {
+ sublist = PyList_New(4);
+ PyList_SET_ITEM(sublist, 0, PyFloat_FromDouble(mat[i][0]));
+ PyList_SET_ITEM(sublist, 1, PyFloat_FromDouble(mat[i][1]));
+ PyList_SET_ITEM(sublist, 2, PyFloat_FromDouble(mat[i][2]));
+ PyList_SET_ITEM(sublist, 2, PyFloat_FromDouble(mat[i][3]));
+ PyList_SET_ITEM(list, i, sublist);
+ }
+
+ return list;
+#endif
}
PyObject* PyObjectFrom(const MT_Matrix3x3 &mat)
{
+#if 0
return Py_BuildValue("[[fff][fff][fff]]",
mat[0][0], mat[0][1], mat[0][2],
mat[1][0], mat[1][1], mat[1][2],
mat[2][0], mat[2][1], mat[2][2]);
+#else
+ PyObject *list = PyList_New(3);
+ PyObject *sublist;
+ int i;
+
+ for(i=0; i < 3; i++) {
+ sublist = PyList_New(3);
+ PyList_SET_ITEM(sublist, 0, PyFloat_FromDouble(mat[i][0]));
+ PyList_SET_ITEM(sublist, 1, PyFloat_FromDouble(mat[i][1]));
+ PyList_SET_ITEM(sublist, 2, PyFloat_FromDouble(mat[i][2]));
+ PyList_SET_ITEM(list, i, sublist);
+ }
+
+ return list;
+#endif
}
PyObject* PyObjectFrom(const MT_Tuple4 &vec)
{
+#if 0
return Py_BuildValue("[ffff]",
vec[0], vec[1], vec[2], vec[3]);
+#else
+ PyObject *list = PyList_New(4);
+ PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0]));
+ PyList_SET_ITEM(list, 1, PyFloat_FromDouble(vec[1]));
+ PyList_SET_ITEM(list, 2, PyFloat_FromDouble(vec[2]));
+ PyList_SET_ITEM(list, 3, PyFloat_FromDouble(vec[3]));
+ return list;
+#endif
}
PyObject* PyObjectFrom(const MT_Tuple3 &vec)
{
+#if 0
return Py_BuildValue("[fff]",
vec[0], vec[1], vec[2]);
+#else
+ PyObject *list = PyList_New(3);
+ PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0]));
+ PyList_SET_ITEM(list, 1, PyFloat_FromDouble(vec[1]));
+ PyList_SET_ITEM(list, 2, PyFloat_FromDouble(vec[2]));
+ return list;
+#endif
}
PyObject* PyObjectFrom(const MT_Tuple2 &vec)
{
+#if 0
return Py_BuildValue("[ff]",
vec[0], vec[1]);
+#else
+ PyObject *list = PyList_New(2);
+ PyList_SET_ITEM(list, 0, PyFloat_FromDouble(vec[0]));
+ PyList_SET_ITEM(list, 1, PyFloat_FromDouble(vec[1]));
+ return list;
+#endif
}
diff --git a/source/gameengine/Ketsji/KX_PyMath.h b/source/gameengine/Ketsji/KX_PyMath.h
index 4e383e9b3d4..39c9c358792 100644
--- a/source/gameengine/Ketsji/KX_PyMath.h
+++ b/source/gameengine/Ketsji/KX_PyMath.h
@@ -131,20 +131,6 @@ bool PyVecTo(PyObject* pyval, T& vec)
}
/**
- * Converts a python argument to an MT class.
- * This paramater expects arguments as passed to a python method.
- */
-template<class T>
-bool PyVecArgTo(PyObject* args, T& vec)
-{
- PyObject* pylist;
- if (PyArg_ParseTuple(args,"O",&pylist))
- return PyVecTo(pylist, vec);
-
- return false;
-}
-
-/**
* Converts an MT_Matrix4x4 to a python object.
*/
PyObject* PyObjectFrom(const MT_Matrix4x4 &mat);
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index 60921449037..965c4ed2ba3 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -47,6 +47,7 @@
#include "KX_PyConstraintBinding.h"
#include "KX_KetsjiEngine.h"
+#include "KX_RadarSensor.h"
#include "SCA_IInputDevice.h"
#include "SCA_PropertySensor.h"
@@ -128,10 +129,10 @@ static PyObject* gPyGetRandomFloat(PyObject*)
return PyFloat_FromDouble(MT_random());
}
-static PyObject* gPySetGravity(PyObject*, PyObject* args)
+static PyObject* gPySetGravity(PyObject*, PyObject* value)
{
- MT_Vector3 vec = MT_Vector3(0., 0., 0.);
- if (!PyVecArgTo(args, vec))
+ MT_Vector3 vec;
+ if (!PyVecTo(value, vec))
return NULL;
if (gp_KetsjiScene)
@@ -199,7 +200,7 @@ static PyObject* gPyGetSpectrum(PyObject*)
}
-
+#if 0 // unused
static PyObject* gPyStartDSP(PyObject*, PyObject* args)
{
SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance();
@@ -216,7 +217,7 @@ static PyObject* gPyStartDSP(PyObject*, PyObject* args)
Py_RETURN_NONE;
}
-
+#endif
static PyObject* gPyStopDSP(PyObject*, PyObject* args)
@@ -260,7 +261,7 @@ static PyObject* gPySetPhysicsTicRate(PyObject*, PyObject* args)
PHY_GetActiveEnvironment()->setFixedTimeStep(true,ticrate);
Py_RETURN_NONE;
}
-
+#if 0 // unused
static PyObject* gPySetPhysicsDebug(PyObject*, PyObject* args)
{
int debugMode;
@@ -270,7 +271,7 @@ static PyObject* gPySetPhysicsDebug(PyObject*, PyObject* args)
PHY_GetActiveEnvironment()->setDebugMode(debugMode);
Py_RETURN_NONE;
}
-
+#endif
static PyObject* gPyGetPhysicsTicRate(PyObject*)
@@ -332,6 +333,32 @@ static PyObject* gPyGetCurrentScene(PyObject* self)
return (PyObject*) gp_KetsjiScene;
}
+static STR_String gPyGetSceneList_doc =
+"getSceneList()\n"
+"Return a list of converted scenes.\n";
+static PyObject* gPyGetSceneList(PyObject* self)
+{
+ KX_KetsjiEngine* m_engine = KX_GetActiveEngine();
+ //CListValue* list = new CListValue();
+ PyObject* list;
+ KX_SceneList* scenes = m_engine->CurrentScenes();
+ int numScenes = scenes->size();
+ int i;
+
+ list = PyList_New(numScenes);
+
+ for (i=0;i<numScenes;i++)
+ {
+ KX_Scene* scene = scenes->at(i);
+ //list->Add(scene);
+ PyList_SET_ITEM(list, i, scene);
+ Py_INCREF(scene);
+
+ }
+
+ return (PyObject*)list;
+}
+
static PyObject *pyPrintExt(PyObject *,PyObject *,PyObject *)
{
#define pprint(x) std::cout << x << std::endl;
@@ -411,11 +438,13 @@ static struct PyMethodDef game_methods[] = {
METH_NOARGS, (PY_METHODCHAR)SCA_PythonController::sPyGetCurrentController__doc__},
{"getCurrentScene", (PyCFunction) gPyGetCurrentScene,
METH_NOARGS, (PY_METHODCHAR)gPyGetCurrentScene_doc.Ptr()},
+ {"getSceneList", (PyCFunction) gPyGetSceneList,
+ METH_NOARGS, (PY_METHODCHAR)gPyGetSceneList_doc.Ptr()},
{"addActiveActuator",(PyCFunction) SCA_PythonController::sPyAddActiveActuator,
METH_VARARGS, (PY_METHODCHAR)SCA_PythonController::sPyAddActiveActuator__doc__},
{"getRandomFloat",(PyCFunction) gPyGetRandomFloat,
METH_NOARGS, (PY_METHODCHAR)gPyGetRandomFloat_doc.Ptr()},
- {"setGravity",(PyCFunction) gPySetGravity, METH_VARARGS, (PY_METHODCHAR)"set Gravitation"},
+ {"setGravity",(PyCFunction) gPySetGravity, METH_O, (PY_METHODCHAR)"set Gravitation"},
{"getSpectrum",(PyCFunction) gPyGetSpectrum, METH_NOARGS, (PY_METHODCHAR)"get audio spectrum"},
{"stopDSP",(PyCFunction) gPyStopDSP, METH_VARARGS, (PY_METHODCHAR)"stop using the audio dsp (for performance reasons)"},
{"getLogicTicRate", (PyCFunction) gPyGetLogicTicRate, METH_NOARGS, (PY_METHODCHAR)"Gets the logic tic rate"},
@@ -545,11 +574,11 @@ static PyObject* gPyGetFocalLength(PyObject*, PyObject*, PyObject*)
Py_RETURN_NONE;
}
-static PyObject* gPySetBackgroundColor(PyObject*, PyObject* args)
+static PyObject* gPySetBackgroundColor(PyObject*, PyObject* value)
{
- MT_Vector4 vec = MT_Vector4(0., 0., 0.3, 0.);
- if (!PyVecArgTo(args, vec))
+ MT_Vector4 vec;
+ if (!PyVecTo(value, vec))
return NULL;
if (gp_Canvas)
@@ -561,11 +590,11 @@ static PyObject* gPySetBackgroundColor(PyObject*, PyObject* args)
-static PyObject* gPySetMistColor(PyObject*, PyObject* args)
+static PyObject* gPySetMistColor(PyObject*, PyObject* value)
{
- MT_Vector3 vec = MT_Vector3(0., 0., 0.);
- if (!PyVecArgTo(args, vec))
+ MT_Vector3 vec;
+ if (!PyVecTo(value, vec))
return NULL;
if (!gp_Rasterizer) {
@@ -616,11 +645,11 @@ static PyObject* gPySetMistEnd(PyObject*, PyObject* args)
}
-static PyObject* gPySetAmbientColor(PyObject*, PyObject* args)
+static PyObject* gPySetAmbientColor(PyObject*, PyObject* value)
{
- MT_Vector3 vec = MT_Vector3(0., 0., 0.);
- if (!PyVecArgTo(args, vec))
+ MT_Vector3 vec;
+ if (!PyVecTo(value, vec))
return NULL;
if (!gp_Rasterizer) {
@@ -815,9 +844,9 @@ static PyObject* gPyDrawLine(PyObject*, PyObject* args)
if (!PyArg_ParseTuple(args,"OOO",&ob_from,&ob_to,&ob_color))
return NULL;
- MT_Vector3 from(0., 0., 0.);
- MT_Vector3 to(0., 0., 0.);
- MT_Vector3 color(0., 0., 0.);
+ MT_Vector3 from;
+ MT_Vector3 to;
+ MT_Vector3 color;
if (!PyVecTo(ob_from, from))
return NULL;
if (!PyVecTo(ob_to, to))
@@ -843,9 +872,9 @@ static struct PyMethodDef rasterizer_methods[] = {
METH_VARARGS, "showMouse(bool visible)"},
{"setMousePosition",(PyCFunction) gPySetMousePosition,
METH_VARARGS, "setMousePosition(int x,int y)"},
- {"setBackgroundColor",(PyCFunction)gPySetBackgroundColor,METH_VARARGS,"set Background Color (rgb)"},
- {"setAmbientColor",(PyCFunction)gPySetAmbientColor,METH_VARARGS,"set Ambient Color (rgb)"},
- {"setMistColor",(PyCFunction)gPySetMistColor,METH_VARARGS,"set Mist Color (rgb)"},
+ {"setBackgroundColor",(PyCFunction)gPySetBackgroundColor,METH_O,"set Background Color (rgb)"},
+ {"setAmbientColor",(PyCFunction)gPySetAmbientColor,METH_O,"set Ambient Color (rgb)"},
+ {"setMistColor",(PyCFunction)gPySetMistColor,METH_O,"set Mist Color (rgb)"},
{"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"},
{"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"},
{"enableMotionBlur",(PyCFunction)gPyEnableMotionBlur,METH_VARARGS,"enable motion blur"},
@@ -1035,6 +1064,14 @@ PyObject* initGameLogic(KX_KetsjiEngine *engine, KX_Scene* scene) // quick hack
KX_MACRO_addTypesToDict(d, KX_STATE29, (1<<28));
KX_MACRO_addTypesToDict(d, KX_STATE30, (1<<29));
+ /* Radar Sensor */
+ KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_POS_X, KX_RadarSensor::KX_RADAR_AXIS_POS_X);
+ KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_POS_Y, KX_RadarSensor::KX_RADAR_AXIS_POS_Y);
+ KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_POS_Z, KX_RadarSensor::KX_RADAR_AXIS_POS_Z);
+ KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_NEG_X, KX_RadarSensor::KX_RADAR_AXIS_NEG_Y);
+ KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_NEG_Y, KX_RadarSensor::KX_RADAR_AXIS_NEG_X);
+ KX_MACRO_addTypesToDict(d, KX_RADAR_AXIS_NEG_Z, KX_RadarSensor::KX_RADAR_AXIS_NEG_Z);
+
// Check for errors
if (PyErr_Occurred())
{
diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp
index 244e9b75d8e..fa8998cd81d 100644
--- a/source/gameengine/Ketsji/KX_RadarSensor.cpp
+++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp
@@ -28,6 +28,7 @@
#include "KX_RadarSensor.h"
#include "KX_GameObject.h"
+#include "KX_PyMath.h"
#include "PHY_IPhysicsController.h"
#ifdef HAVE_CONFIG_H
@@ -170,8 +171,18 @@ void KX_RadarSensor::SynchronizeTransform()
{
}
}
- m_cone_origin = trans.getOrigin();
- m_cone_target = trans(MT_Point3(0, -m_coneheight/2.0 ,0));
+
+ //Using a temp variable to translate MT_Point3 to float[3].
+ //float[3] works better for the Python interface.
+ MT_Point3 temp = trans.getOrigin();
+ m_cone_origin[0] = temp[0];
+ m_cone_origin[1] = temp[1];
+ m_cone_origin[2] = temp[2];
+
+ temp = trans(MT_Point3(0, -m_coneheight/2.0 ,0));
+ m_cone_target[0] = temp[0];
+ m_cone_target[1] = temp[1];
+ m_cone_target[2] = temp[2];
if (m_physCtrl)
@@ -186,10 +197,58 @@ void KX_RadarSensor::SynchronizeTransform()
}
/* ------------------------------------------------------------------------- */
-/* Python functions */
+/* Python Functions */
/* ------------------------------------------------------------------------- */
-/* Integration hooks ------------------------------------------------------- */
+//Deprecated ----->
+/* getConeOrigin */
+const char KX_RadarSensor::GetConeOrigin_doc[] =
+"getConeOrigin()\n"
+"\tReturns the origin of the cone with which to test. The origin\n"
+"\tis in the middle of the cone.";
+PyObject* KX_RadarSensor::PyGetConeOrigin(PyObject* self) {
+ ShowDeprecationWarning("getConeOrigin()", "the coneOrigin property");
+
+ PyObject *retVal = PyList_New(3);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_origin[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_origin[1]));
+ PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_origin[2]));
+
+ return retVal;
+}
+
+/* getConeOrigin */
+const char KX_RadarSensor::GetConeTarget_doc[] =
+"getConeTarget()\n"
+"\tReturns the center of the bottom face of the cone with which to test.\n";
+PyObject* KX_RadarSensor::PyGetConeTarget(PyObject* self) {
+ ShowDeprecationWarning("getConeTarget()", "the coneTarget property");
+
+ PyObject *retVal = PyList_New(3);
+
+ PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_target[0]));
+ PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_target[1]));
+ PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_target[2]));
+
+ return retVal;
+}
+
+/* getConeHeight */
+const char KX_RadarSensor::GetConeHeight_doc[] =
+"getConeHeight()\n"
+"\tReturns the height of the cone with which to test.\n";
+PyObject* KX_RadarSensor::PyGetConeHeight(PyObject* self) {
+
+ ShowDeprecationWarning("getConeHeight()", "the distance property");
+
+ return PyFloat_FromDouble(m_coneheight);
+}
+//<----- Deprecated
+
+/* ------------------------------------------------------------------------- */
+/* Python Integration Hooks */
+/* ------------------------------------------------------------------------- */
PyTypeObject KX_RadarSensor::Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
@@ -220,60 +279,39 @@ PyParentObject KX_RadarSensor::Parents[] = {
};
PyMethodDef KX_RadarSensor::Methods[] = {
+ //Deprecated ----->
{"getConeOrigin", (PyCFunction) KX_RadarSensor::sPyGetConeOrigin,
METH_VARARGS, (PY_METHODCHAR)GetConeOrigin_doc},
{"getConeTarget", (PyCFunction) KX_RadarSensor::sPyGetConeTarget,
METH_VARARGS, (PY_METHODCHAR)GetConeTarget_doc},
{"getConeHeight", (PyCFunction) KX_RadarSensor::sPyGetConeHeight,
METH_VARARGS, (PY_METHODCHAR)GetConeHeight_doc},
- {NULL,NULL,NULL,NULL} //Sentinel
+ //<-----
+ {NULL} //Sentinel
};
-PyObject* KX_RadarSensor::_getattr(const STR_String& attr) {
- _getattr_up(KX_TouchSensor);
-}
-
-/* getConeOrigin */
-const char KX_RadarSensor::GetConeOrigin_doc[] =
-"getConeOrigin()\n"
-"\tReturns the origin of the cone with which to test. The origin\n"
-"\tis in the middle of the cone.";
-PyObject* KX_RadarSensor::PyGetConeOrigin(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
- PyObject *retVal = PyList_New(3);
-
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_origin[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_origin[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_origin[2]));
-
- return retVal;
-}
+PyAttributeDef KX_RadarSensor::Attributes[] = {
+ KX_PYATTRIBUTE_FLOAT_ARRAY_RO("coneOrigin", KX_RadarSensor, m_cone_origin, 3),
+ KX_PYATTRIBUTE_FLOAT_ARRAY_RO("coneTarget", KX_RadarSensor, m_cone_target, 3),
+ KX_PYATTRIBUTE_FLOAT_RW("angle", 0, 360, KX_RadarSensor, m_coneradius),
+ KX_PYATTRIBUTE_INT_RW("axis", 0, 5, true, KX_RadarSensor, m_axis),
+ {NULL} //Sentinel
+};
-/* getConeOrigin */
-const char KX_RadarSensor::GetConeTarget_doc[] =
-"getConeTarget()\n"
-"\tReturns the center of the bottom face of the cone with which to test.\n";
-PyObject* KX_RadarSensor::PyGetConeTarget(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
- PyObject *retVal = PyList_New(3);
-
- PyList_SetItem(retVal, 0, PyFloat_FromDouble(m_cone_target[0]));
- PyList_SetItem(retVal, 1, PyFloat_FromDouble(m_cone_target[1]));
- PyList_SetItem(retVal, 2, PyFloat_FromDouble(m_cone_target[2]));
-
- return retVal;
-}
+PyObject* KX_RadarSensor::_getattr(const char *attr)
+{
+ PyObject* object = _getattr_self(Attributes, this, attr);
+ if (object != NULL)
+ return object;
-/* getConeOrigin */
-const char KX_RadarSensor::GetConeHeight_doc[] =
-"getConeHeight()\n"
-"\tReturns the height of the cone with which to test.\n";
-PyObject* KX_RadarSensor::PyGetConeHeight(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
- return PyFloat_FromDouble(m_coneheight);
+ _getattr_up(KX_NearSensor);
}
+int KX_RadarSensor::_setattr(const char *attr, PyObject* value)
+{
+ int ret = _setattr_self(Attributes, this, attr, value);
+ if (ret >= 0)
+ return ret;
+ return KX_NearSensor::_setattr(attr, value);
+}
diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h
index 7272b219e37..6dfe0c42f5d 100644
--- a/source/gameengine/Ketsji/KX_RadarSensor.h
+++ b/source/gameengine/Ketsji/KX_RadarSensor.h
@@ -40,23 +40,23 @@ class KX_RadarSensor : public KX_NearSensor
protected:
Py_Header;
- MT_Scalar m_coneradius;
+ float m_coneradius;
/**
* Height of the cone.
*/
- MT_Scalar m_coneheight;
+ float m_coneheight;
int m_axis;
/**
* The previous position of the origin of the cone.
*/
- MT_Point3 m_cone_origin;
+ float m_cone_origin[3];
/**
* The previous direction of the cone (origin to bottom plane).
*/
- MT_Point3 m_cone_target;
+ float m_cone_target[3];
public:
@@ -80,13 +80,23 @@ public:
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
-
- virtual PyObject* _getattr(const STR_String& attr);
+ enum RadarAxis {
+ KX_RADAR_AXIS_POS_X = 0,
+ KX_RADAR_AXIS_POS_Y,
+ KX_RADAR_AXIS_POS_Z,
+ KX_RADAR_AXIS_NEG_X,
+ KX_RADAR_AXIS_NEG_Y,
+ KX_RADAR_AXIS_NEG_Z
+ };
- KX_PYMETHOD_DOC(KX_RadarSensor,GetConeOrigin);
- KX_PYMETHOD_DOC(KX_RadarSensor,GetConeTarget);
- KX_PYMETHOD_DOC(KX_RadarSensor,GetConeHeight);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject* value);
+ //Deprecated ----->
+ KX_PYMETHOD_DOC_NOARGS(KX_RadarSensor,GetConeOrigin);
+ KX_PYMETHOD_DOC_NOARGS(KX_RadarSensor,GetConeTarget);
+ KX_PYMETHOD_DOC_NOARGS(KX_RadarSensor,GetConeHeight);
+ //<-----
};
#endif //__KX_RADAR_SENSOR_H
diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp
index e24fb773eac..ce12b983147 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.cpp
+++ b/source/gameengine/Ketsji/KX_RaySensor.cpp
@@ -38,6 +38,7 @@
#include "KX_GameObject.h"
#include "KX_Scene.h"
#include "KX_RayCast.h"
+#include "KX_PyMath.h"
#include "PHY_IPhysicsEnvironment.h"
#include "KX_IPhysicsController.h"
#include "PHY_IPhysicsController.h"
@@ -179,8 +180,8 @@ bool KX_RaySensor::Evaluate(CValue* event)
bool reset = m_reset && m_level;
m_rayHit = false;
m_hitObject = NULL;
- m_hitPosition = MT_Vector3(0,0,0);
- m_hitNormal = MT_Vector3(1,0,0);
+ m_hitPosition.setValue(0,0,0);
+ m_hitNormal.setValue(1,0,0);
KX_GameObject* obj = (KX_GameObject*)GetParent();
MT_Point3 frompoint = obj->NodeGetWorldPosition();
@@ -335,89 +336,56 @@ PyParentObject KX_RaySensor::Parents[] = {
};
PyMethodDef KX_RaySensor::Methods[] = {
- {"getHitObject",(PyCFunction) KX_RaySensor::sPyGetHitObject,METH_VARARGS, (PY_METHODCHAR)GetHitObject_doc},
- {"getHitPosition",(PyCFunction) KX_RaySensor::sPyGetHitPosition,METH_VARARGS, (PY_METHODCHAR)GetHitPosition_doc},
- {"getHitNormal",(PyCFunction) KX_RaySensor::sPyGetHitNormal,METH_VARARGS, (PY_METHODCHAR)GetHitNormal_doc},
- {"getRayDirection",(PyCFunction) KX_RaySensor::sPyGetRayDirection,METH_VARARGS, (PY_METHODCHAR)GetRayDirection_doc},
+ {"getHitObject",(PyCFunction) KX_RaySensor::sPyGetHitObject,METH_NOARGS, (PY_METHODCHAR)GetHitObject_doc},
+ {"getHitPosition",(PyCFunction) KX_RaySensor::sPyGetHitPosition,METH_NOARGS, (PY_METHODCHAR)GetHitPosition_doc},
+ {"getHitNormal",(PyCFunction) KX_RaySensor::sPyGetHitNormal,METH_NOARGS, (PY_METHODCHAR)GetHitNormal_doc},
+ {"getRayDirection",(PyCFunction) KX_RaySensor::sPyGetRayDirection,METH_NOARGS, (PY_METHODCHAR)GetRayDirection_doc},
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_RaySensor::Attributes[] = {
+ { NULL } //Sentinel
+};
+
const char KX_RaySensor::GetHitObject_doc[] =
"getHitObject()\n"
"\tReturns the name of the object that was hit by this ray.\n";
-PyObject* KX_RaySensor::PyGetHitObject(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_RaySensor::PyGetHitObject(PyObject* self)
{
if (m_hitObject)
{
return m_hitObject->AddRef();
}
- Py_Return;
+ Py_RETURN_NONE;
}
const char KX_RaySensor::GetHitPosition_doc[] =
"getHitPosition()\n"
"\tReturns the position (in worldcoordinates) where the object was hit by this ray.\n";
-PyObject* KX_RaySensor::PyGetHitPosition(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_RaySensor::PyGetHitPosition(PyObject* self)
{
-
- MT_Point3 pos = m_hitPosition;
-
- PyObject* resultlist = PyList_New(3);
- int index;
- for (index=0;index<3;index++)
- {
- PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index]));
- }
- return resultlist;
-
+ return PyObjectFrom(m_hitPosition);
}
const char KX_RaySensor::GetRayDirection_doc[] =
"getRayDirection()\n"
"\tReturns the direction from the ray (in worldcoordinates) .\n";
-PyObject* KX_RaySensor::PyGetRayDirection(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_RaySensor::PyGetRayDirection(PyObject* self)
{
-
- MT_Vector3 dir = m_rayDirection;
-
- PyObject* resultlist = PyList_New(3);
- int index;
- for (index=0;index<3;index++)
- {
- PyList_SetItem(resultlist,index,PyFloat_FromDouble(dir[index]));
- }
- return resultlist;
-
+ return PyObjectFrom(m_rayDirection);
}
const char KX_RaySensor::GetHitNormal_doc[] =
"getHitNormal()\n"
"\tReturns the normal (in worldcoordinates) of the object at the location where the object was hit by this ray.\n";
-PyObject* KX_RaySensor::PyGetHitNormal(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_RaySensor::PyGetHitNormal(PyObject* self)
{
- MT_Vector3 pos = m_hitNormal;
-
- PyObject* resultlist = PyList_New(3);
- int index;
- for (index=0;index<3;index++)
- {
- PyList_SetItem(resultlist,index,PyFloat_FromDouble(pos[index]));
- }
- return resultlist;
-
+ return PyObjectFrom(m_hitNormal);
}
-PyObject* KX_RaySensor::_getattr(const STR_String& attr) {
+PyObject* KX_RaySensor::_getattr(const char *attr) {
_getattr_up(SCA_ISensor);
}
diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h
index 02a755fedc1..09d8bc1369a 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.h
+++ b/source/gameengine/Ketsji/KX_RaySensor.h
@@ -74,12 +74,12 @@ public:
bool RayHit(KX_ClientObjectInfo* client, KX_RayCast* result, void * const data);
bool NeedRayCast(KX_ClientObjectInfo* client);
- KX_PYMETHOD_DOC(KX_RaySensor,GetHitObject);
- KX_PYMETHOD_DOC(KX_RaySensor,GetHitPosition);
- KX_PYMETHOD_DOC(KX_RaySensor,GetHitNormal);
- KX_PYMETHOD_DOC(KX_RaySensor,GetRayDirection);
+ KX_PYMETHOD_DOC_NOARGS(KX_RaySensor,GetHitObject);
+ KX_PYMETHOD_DOC_NOARGS(KX_RaySensor,GetHitPosition);
+ KX_PYMETHOD_DOC_NOARGS(KX_RaySensor,GetHitNormal);
+ KX_PYMETHOD_DOC_NOARGS(KX_RaySensor,GetRayDirection);
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
};
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
index 5777f54b799..68b704f4889 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
@@ -188,9 +188,7 @@ PyParentObject KX_SCA_AddObjectActuator::Parents[] = {
NULL
};
PyMethodDef KX_SCA_AddObjectActuator::Methods[] = {
- {"setObject", (PyCFunction) KX_SCA_AddObjectActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc},
{"setTime", (PyCFunction) KX_SCA_AddObjectActuator::sPySetTime, METH_O, (PY_METHODCHAR)SetTime_doc},
- {"getObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc},
{"getTime", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetTime, METH_NOARGS, (PY_METHODCHAR)GetTime_doc},
{"getLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLinearVelocity, METH_NOARGS, (PY_METHODCHAR)GetLinearVelocity_doc},
{"setLinearVelocity", (PyCFunction) KX_SCA_AddObjectActuator::sPySetLinearVelocity, METH_VARARGS, (PY_METHODCHAR)SetLinearVelocity_doc},
@@ -199,15 +197,52 @@ PyMethodDef KX_SCA_AddObjectActuator::Methods[] = {
{"getLastCreatedObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetLastCreatedObject, METH_NOARGS,"getLastCreatedObject() : get the object handle to the last created object\n"},
{"instantAddObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyInstantAddObject, METH_NOARGS,"instantAddObject() : immediately add object without delay\n"},
+ // ---> deprecated
+ {"setObject", (PyCFunction) KX_SCA_AddObjectActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc},
+ {"getObject", (PyCFunction) KX_SCA_AddObjectActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc},
+
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_SCA_AddObjectActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
-PyObject* KX_SCA_AddObjectActuator::_getattr(const STR_String& attr)
+PyObject* KX_SCA_AddObjectActuator::_getattr(const char *attr)
{
+ if (!strcmp(attr, "object")) {
+ if (!m_OriginalObject) Py_RETURN_NONE;
+ else return m_OriginalObject->AddRef();
+ } else if (!strcmp(attr, "objectLastCreated")) {
+ if (!m_OriginalObject) Py_RETURN_NONE;
+ else return m_lastCreatedObject->AddRef();
+ }
+
_getattr_up(SCA_IActuator);
}
+int KX_SCA_AddObjectActuator::_setattr(const char *attr, PyObject* value) {
+
+ if (!strcmp(attr, "object")) {
+ KX_GameObject *gameobj;
+
+ if (!ConvertPythonToGameObject(value, &gameobj, true))
+ return 1; // ConvertPythonToGameObject sets the error
+
+ if (m_OriginalObject != NULL)
+ m_OriginalObject->UnregisterActuator(this);
+
+ m_OriginalObject = (SCA_IObject*)gameobj;
+
+ if (m_OriginalObject)
+ m_OriginalObject->RegisterActuator(this);
+
+ return 0;
+ }
+
+ return SCA_IActuator::_setattr(attr, value);
+}
+
/* 1. setObject */
const char KX_SCA_AddObjectActuator::SetObject_doc[] =
"setObject(object)\n"
@@ -218,6 +253,8 @@ PyObject* KX_SCA_AddObjectActuator::PySetObject(PyObject* self, PyObject* value)
{
KX_GameObject *gameobj;
+ ShowDeprecationWarning("setObject()", "the object property");
+
if (!ConvertPythonToGameObject(value, &gameobj, true))
return NULL; // ConvertPythonToGameObject sets the error
@@ -277,6 +314,9 @@ const char KX_SCA_AddObjectActuator::GetObject_doc[] =
PyObject* KX_SCA_AddObjectActuator::PyGetObject(PyObject* self, PyObject* args)
{
int ret_name_only = 1;
+
+ ShowDeprecationWarning("getObject()", "the object property");
+
if (!PyArg_ParseTuple(args, "|i", &ret_name_only))
return NULL;
diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
index 278d4180284..18298cbcb0c 100644
--- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
@@ -60,13 +60,16 @@ class KX_SCA_AddObjectActuator : public SCA_IActuator
/// Linear velocity upon creation of the object.
MT_Vector3 m_linear_velocity;
+ /// Apply the velocity locally
+ bool m_localLinvFlag;
/// Angular velocity upon creation of the object.
MT_Vector3 m_angular_velocity;
-
/// Apply the velocity locally
- bool m_localLinvFlag;
- bool m_localAngvFlag;
+ bool m_localAngvFlag;
+
+
+
SCA_IObject* m_lastCreatedObject;
@@ -107,10 +110,8 @@ public:
virtual bool
Update();
- virtual PyObject*
- _getattr(
- const STR_String& attr
- );
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject* value);
SCA_IObject*
GetLastCreatedObject(
diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
index 176ccf1a84a..394bb667728 100644
--- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.cpp
@@ -85,9 +85,12 @@ PyMethodDef KX_SCA_DynamicActuator::Methods[] = {
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_SCA_DynamicActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
-PyObject* KX_SCA_DynamicActuator::_getattr(const STR_String& attr)
+PyObject* KX_SCA_DynamicActuator::_getattr(const char *attr)
{
_getattr_up(SCA_IActuator);
}
@@ -115,7 +118,7 @@ KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, setOperation,
return NULL;
}
m_dyn_operation= dyn_operation;
- Py_Return;
+ Py_RETURN_NONE;
}
KX_PYMETHODDEF_DOC(KX_SCA_DynamicActuator, getOperation,
diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h
index de2fab68d15..a82cddd66a7 100644
--- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h
@@ -64,10 +64,7 @@ class KX_SCA_DynamicActuator : public SCA_IActuator
virtual bool
Update();
- virtual PyObject*
- _getattr(
- const STR_String& attr
- );
+ virtual PyObject* _getattr(const char *attr);
/* 1. setOperation */
KX_PYMETHOD_DOC(KX_SCA_DynamicActuator,setOperation);
diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp
index ec29448907f..9268a1df5f0 100644
--- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.cpp
@@ -127,8 +127,11 @@ PyMethodDef KX_SCA_EndObjectActuator::Methods[] = {
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_SCA_EndObjectActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
-PyObject* KX_SCA_EndObjectActuator::_getattr(const STR_String& attr)
+PyObject* KX_SCA_EndObjectActuator::_getattr(const char *attr)
{
_getattr_up(SCA_IActuator);
}
diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
index add9c05b000..12118743f0a 100644
--- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
@@ -64,10 +64,7 @@ class KX_SCA_EndObjectActuator : public SCA_IActuator
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject*
- _getattr(
- const STR_String& attr
- );
+ virtual PyObject* _getattr(const char *attr);
}; /* end of class KX_EditObjectActuator : public SCA_PropertyActuator */
diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
index 261d9ec8f0c..502990b2b27 100644
--- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.cpp
@@ -89,9 +89,11 @@ PyMethodDef KX_SCA_ReplaceMeshActuator::Methods[] = {
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_SCA_ReplaceMeshActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
-
-PyObject* KX_SCA_ReplaceMeshActuator::_getattr(const STR_String& attr)
+PyObject* KX_SCA_ReplaceMeshActuator::_getattr(const char *attr)
{
_getattr_up(SCA_IActuator);
}
diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
index 1da154cc222..0ba60650683 100644
--- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
+++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
@@ -69,10 +69,7 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator
virtual bool
Update();
- virtual PyObject*
- _getattr(
- const STR_String& attr
- );
+ virtual PyObject* _getattr(const char *attr);
void InstantReplaceMesh();
/* 1. setMesh */
diff --git a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp
index d651373869a..151270cbd68 100644
--- a/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp
+++ b/source/gameengine/Ketsji/KX_SG_BoneParentNodeRelationship.cpp
@@ -97,11 +97,11 @@ UpdateChildCoordinates(
child_transform = parent_matrix * child_transform;
// Recompute the child transform components from the transform.
- child_w_scale = MT_Vector3(
+ child_w_scale.setValue(
MT_Vector3(child_transform[0][0], child_transform[0][1], child_transform[0][2]).length(),
MT_Vector3(child_transform[1][0], child_transform[1][1], child_transform[1][2]).length(),
MT_Vector3(child_transform[2][0], child_transform[2][1], child_transform[2][2]).length());
- child_w_rotation = MT_Matrix3x3(child_transform[0][0], child_transform[0][1], child_transform[0][2],
+ child_w_rotation.setValue(child_transform[0][0], child_transform[0][1], child_transform[0][2],
child_transform[1][0], child_transform[1][1], child_transform[1][2],
child_transform[2][0], child_transform[2][1], child_transform[2][2]);
child_w_rotation.scale(1.0/child_w_scale[0], 1.0/child_w_scale[1], 1.0/child_w_scale[2]);
@@ -113,16 +113,15 @@ UpdateChildCoordinates(
}
}
- if (!valid_parent_transform)
+ if (valid_parent_transform)
{
- child_w_scale = child_scale;
- child_w_pos = child_pos;
- child_w_rotation = child_rotation;
+ child->SetWorldScale(child_w_scale);
+ child->SetWorldPosition(child_w_pos);
+ child->SetWorldOrientation(child_w_rotation);
+ }
+ else {
+ child->SetWorldFromLocalTransform();
}
-
- child->SetWorldScale(child_w_scale);
- child->SetWorldPosition(child_w_pos);
- child->SetWorldOrientation(child_w_rotation);
return valid_parent_transform;
}
diff --git a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
index 0c8e7e28771..0729ec8a902 100644
--- a/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
+++ b/source/gameengine/Ketsji/KX_SG_NodeRelationships.cpp
@@ -55,43 +55,21 @@ UpdateChildCoordinates(
){
MT_assert(child != NULL);
- // This way of accessing child coordinates is a bit cumbersome
- // be nice to have non constant reference access to these values.
-
- const MT_Vector3 & child_scale = child->GetLocalScale();
- const MT_Point3 & child_pos = child->GetLocalPosition();
- const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
-
- // the childs world locations which we will update.
-
- MT_Vector3 child_w_scale;
- MT_Point3 child_w_pos;
- MT_Matrix3x3 child_w_rotation;
-
- if (parent) {
-
+ if (parent==NULL) { /* Simple case */
+ child->SetWorldFromLocalTransform();
+ return false;
+ }
+ else {
+ // the childs world locations which we will update.
const MT_Vector3 & p_world_scale = parent->GetWorldScaling();
const MT_Point3 & p_world_pos = parent->GetWorldPosition();
const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation();
- child_w_scale = p_world_scale * child_scale;
- child_w_rotation = p_world_rotation * child_rotation;
-
- child_w_pos = p_world_pos + p_world_scale *
- (p_world_rotation * child_pos);
-
- } else {
-
- child_w_scale = child_scale;
- child_w_pos = child_pos;
- child_w_rotation = child_rotation;
+ child->SetWorldScale(p_world_scale * child->GetLocalScale());
+ child->SetWorldOrientation(p_world_rotation * child->GetLocalOrientation());
+ child->SetWorldPosition(p_world_pos + p_world_scale * (p_world_rotation * child->GetLocalPosition()));
+ return true;
}
-
- child->SetWorldScale(child_w_scale);
- child->SetWorldPosition(child_w_pos);
- child->SetWorldOrientation(child_w_rotation);
-
- return parent != NULL;
}
SG_ParentRelation *
@@ -138,40 +116,14 @@ UpdateChildCoordinates(
){
MT_assert(child != NULL);
-
- const MT_Vector3 & child_scale = child->GetLocalScale();
- const MT_Point3 & child_pos = child->GetLocalPosition();
- const MT_Matrix3x3 & child_rotation = child->GetLocalOrientation();
-
- // the childs world locations which we will update.
+ child->SetWorldScale(child->GetLocalScale());
- MT_Vector3 child_w_scale;
- MT_Point3 child_w_pos;
- MT_Matrix3x3 child_w_rotation;
-
- if (parent) {
-
- // This is a vertex parent so we do not inherit orientation
- // information.
-
- // const MT_Vector3 & p_world_scale = parent->GetWorldScaling(); /*unused*/
- const MT_Point3 & p_world_pos = parent->GetWorldPosition();
- // const MT_Matrix3x3 & p_world_rotation = parent->GetWorldOrientation(); /*unused*/
-
- child_w_scale = child_scale;
- child_w_rotation = child_rotation;
- child_w_pos = p_world_pos + child_pos;
- } else {
-
- child_w_scale = child_scale;
- child_w_pos = child_pos;
- child_w_rotation = child_rotation;
- }
-
- child->SetWorldScale(child_w_scale);
- child->SetWorldPosition(child_w_pos);
- child->SetWorldOrientation(child_w_rotation);
+ if (parent)
+ child->SetWorldPosition(child->GetLocalPosition()+parent->GetWorldPosition());
+ else
+ child->SetWorldPosition(child->GetLocalPosition());
+ child->SetWorldOrientation(child->GetLocalOrientation());
return parent != NULL;
}
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 476a931355f..0fded15f1a1 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -1014,6 +1014,12 @@ void KX_Scene::ReplaceMesh(class CValue* obj,void* meshobj)
blendmesh->dvert!=NULL; // mesh has vertex group
bool releaseParent = true;
+
+ if (oldblendobj==NULL) {
+ std::cout << "warning: ReplaceMesh() new mesh is not used in an object from the current scene, you will get incorrect behavior" << std::endl;
+ bHasShapeKey= bHasDvert= bHasArmature= false;
+ }
+
if (bHasShapeKey)
{
BL_ShapeDeformer* shapeDeformer;
@@ -1511,14 +1517,6 @@ double KX_Scene::getSuspendedDelta()
//----------------------------------------------------------------------------
//Python
-PyMethodDef KX_Scene::Methods[] = {
- KX_PYMETHODTABLE(KX_Scene, getLightList),
- KX_PYMETHODTABLE(KX_Scene, getObjectList),
- KX_PYMETHODTABLE(KX_Scene, getName),
-
- {NULL,NULL} //Sentinel
-};
-
PyTypeObject KX_Scene::Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
@@ -1544,28 +1542,40 @@ PyParentObject KX_Scene::Parents[] = {
NULL
};
-PyObject* KX_Scene::_getattr(const STR_String& attr)
+PyMethodDef KX_Scene::Methods[] = {
+ KX_PYMETHODTABLE(KX_Scene, getLightList),
+ KX_PYMETHODTABLE(KX_Scene, getObjectList),
+ KX_PYMETHODTABLE(KX_Scene, getName),
+ KX_PYMETHODTABLE(KX_Scene, addObject),
+
+ {NULL,NULL} //Sentinel
+};
+
+PyAttributeDef KX_Scene::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* KX_Scene::_getattr(const char *attr)
{
- if (attr == "name")
+ if (!strcmp(attr, "name"))
return PyString_FromString(GetName());
- if (attr == "active_camera")
- {
- KX_Camera *camera = GetActiveCamera();
- camera->AddRef();
- return (PyObject*) camera;
- }
+ if (!strcmp(attr, "objects"))
+ return (PyObject*) m_objectlist->AddRef();
- if (attr == "suspended")
+ if (!strcmp(attr, "active_camera"))
+ return (PyObject*) GetActiveCamera()->AddRef();
+
+ if (!strcmp(attr, "suspended"))
return PyInt_FromLong(m_suspend);
- if (attr == "activity_culling")
+ if (!strcmp(attr, "activity_culling"))
return PyInt_FromLong(m_activity_culling);
- if (attr == "activity_culling_radius")
+ if (!strcmp(attr, "activity_culling_radius"))
return PyFloat_FromDouble(m_activity_box_radius);
- PyObject* value = PyDict_GetItemString(m_attrlist, const_cast<char *>(attr.ReadPtr()));
+ PyObject* value = PyDict_GetItemString(m_attrlist, attr);
if (value)
{
Py_INCREF(value);
@@ -1575,43 +1585,63 @@ PyObject* KX_Scene::_getattr(const STR_String& attr)
_getattr_up(PyObjectPlus);
}
-int KX_Scene::_delattr(const STR_String &attr)
+int KX_Scene::_delattr(const char *attr)
{
- PyDict_DelItemString(m_attrlist, const_cast<char *>(attr.ReadPtr()));
+ PyDict_DelItemString(m_attrlist, attr);
return 0;
}
-int KX_Scene::_setattr(const STR_String &attr, PyObject *pyvalue)
+int KX_Scene::_setattr(const char *attr, PyObject *pyvalue)
{
-
- if (!PyDict_SetItemString(m_attrlist, const_cast<char *>(attr.ReadPtr()), pyvalue))
+ if (!PyDict_SetItemString(m_attrlist, attr, pyvalue))
return 0;
return PyObjectPlus::_setattr(attr, pyvalue);
}
-KX_PYMETHODDEF_DOC(KX_Scene, getLightList,
+KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getLightList,
"getLightList() -> list [KX_Light]\n"
"Returns a list of all lights in the scene.\n"
)
{
- m_lightlist->AddRef();
- return (PyObject*) m_lightlist;
+ return (PyObject*) m_lightlist->AddRef();
}
-KX_PYMETHODDEF_DOC(KX_Scene, getObjectList,
+KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getObjectList,
"getObjectList() -> list [KX_GameObject]\n"
"Returns a list of all game objects in the scene.\n"
)
{
- m_objectlist->AddRef();
- return (PyObject*) m_objectlist;
+ // ShowDeprecationWarning("getObjectList()", "the objects property"); // XXX Grr, why doesnt this work?
+ return (PyObject*) m_objectlist->AddRef();
}
-KX_PYMETHODDEF_DOC(KX_Scene, getName,
+KX_PYMETHODDEF_DOC_NOARGS(KX_Scene, getName,
"getName() -> string\n"
"Returns the name of the scene.\n"
)
{
return PyString_FromString(GetName());
}
+
+KX_PYMETHODDEF_DOC(KX_Scene, addObject,
+"addObject(object, other, time=0)\n"
+"Returns the added object.\n")
+{
+ PyObject *pyob, *pyother;
+ KX_GameObject *ob, *other;
+
+ int time = 0;
+
+ if (!PyArg_ParseTuple(args, "OO|i", &pyob, &pyother, &time))
+ return NULL;
+
+ if (!ConvertPythonToGameObject(pyob, &ob, false)
+ || !ConvertPythonToGameObject(pyother, &other, false))
+ return NULL;
+
+
+ SCA_IObject* replica = AddReplicaObject((SCA_IObject*)ob, other, time);
+ replica->AddRef();
+ return replica;
+} \ No newline at end of file
diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h
index 5f7e1167e27..962db1a9b96 100644
--- a/source/gameengine/Ketsji/KX_Scene.h
+++ b/source/gameengine/Ketsji/KX_Scene.h
@@ -547,9 +547,10 @@ public:
*/
void SetNodeTree(SG_Tree* root);
- KX_PYMETHOD_DOC(KX_Scene, getLightList);
- KX_PYMETHOD_DOC(KX_Scene, getObjectList);
- KX_PYMETHOD_DOC(KX_Scene, getName);
+ KX_PYMETHOD_DOC_NOARGS(KX_Scene, getLightList);
+ KX_PYMETHOD_DOC_NOARGS(KX_Scene, getObjectList);
+ KX_PYMETHOD_DOC_NOARGS(KX_Scene, getName);
+ KX_PYMETHOD_DOC(KX_Scene, addObject);
/*
KX_PYMETHOD_DOC(KX_Scene, getActiveCamera);
KX_PYMETHOD_DOC(KX_Scene, getActiveCamera);
@@ -564,10 +565,12 @@ public:
KX_PYMETHOD_DOC(KX_Scene, setSceneViewport);
*/
- virtual PyObject* _getattr(const STR_String& attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */
- virtual int _setattr(const STR_String &attr, PyObject *pyvalue);
- virtual int _delattr(const STR_String &attr);
+ virtual PyObject* _getattr(const char *attr); /* name, active_camera, gravity, suspended, viewport, framing, activity_culling, activity_culling_radius */
+ virtual int _setattr(const char *attr, PyObject *pyvalue);
+ virtual int _delattr(const char *attr);
+ virtual PyObject* _repr(void) { return PyString_FromString(GetName().ReadPtr()); }
+
/**
* Sets the time the scene was suspended
*/
diff --git a/source/gameengine/Ketsji/KX_SceneActuator.cpp b/source/gameengine/Ketsji/KX_SceneActuator.cpp
index 35484699b17..1cad4e21352 100644
--- a/source/gameengine/Ketsji/KX_SceneActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SceneActuator.cpp
@@ -268,9 +268,11 @@ PyMethodDef KX_SceneActuator::Methods[] =
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_SceneActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
-
-PyObject* KX_SceneActuator::_getattr(const STR_String& attr)
+PyObject* KX_SceneActuator::_getattr(const char *attr)
{
_getattr_up(SCA_IActuator);
}
@@ -295,7 +297,7 @@ PyObject* KX_SceneActuator::PySetUseRestart(PyObject* self,
m_restart = boolArg != 0;
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -333,7 +335,7 @@ PyObject* KX_SceneActuator::PySetScene(PyObject* self,
/* Scene switch is done by name. */
m_nextSceneName = scene_name;
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -368,7 +370,7 @@ PyObject* KX_SceneActuator::PySetCamera(PyObject* self,
m_camera = (KX_Camera*) cam;
if (m_camera)
m_camera->RegisterActuator(this);
- Py_Return;
+ Py_RETURN_NONE;
}
PyErr_Clear();
@@ -388,7 +390,7 @@ PyObject* KX_SceneActuator::PySetCamera(PyObject* self,
m_camera->RegisterActuator(this);
}
- Py_Return;
+ Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h
index 55aaf629d7c..af11af955bf 100644
--- a/source/gameengine/Ketsji/KX_SceneActuator.h
+++ b/source/gameengine/Ketsji/KX_SceneActuator.h
@@ -92,7 +92,7 @@ class KX_SceneActuator : public SCA_IActuator
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
/* 1. set */
/* Removed */
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp
index afa5af3bc04..6de1d67bfdb 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp
@@ -285,9 +285,11 @@ PyMethodDef KX_SoundActuator::Methods[] = {
{NULL,NULL,NULL,NULL} //Sentinel
};
+PyAttributeDef KX_SoundActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
-
-PyObject* KX_SoundActuator::_getattr(const STR_String& attr)
+PyObject* KX_SoundActuator::_getattr(const char *attr)
{
_getattr_up(SCA_IActuator);
}
@@ -302,7 +304,7 @@ PyObject* KX_SoundActuator::PySetFilename(PyObject* self, PyObject* args, PyObje
if (!PyArg_ParseTuple(args, "s", &soundName))
return NULL;
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -332,7 +334,7 @@ PyObject* KX_SoundActuator::PyStartSound(PyObject* self, PyObject* args, PyObjec
// To start the sound you must activate the actuator.
// This function is to restart the sound.
m_soundObject->StartSound();
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -342,7 +344,7 @@ PyObject* KX_SoundActuator::PyPauseSound(PyObject* self, PyObject* args, PyObjec
if (m_soundObject)
// unfortunately, openal does not implement pause correctly, it is equivalent to a stop
m_soundObject->PauseSound();
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -351,7 +353,7 @@ PyObject* KX_SoundActuator::PyStopSound(PyObject* self, PyObject* args, PyObject
{
if (m_soundObject)
m_soundObject->StopSound();
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -365,7 +367,7 @@ PyObject* KX_SoundActuator::PySetGain(PyObject* self, PyObject* args, PyObject*
if (m_soundObject)
m_soundObject->SetGain(gain);
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -389,7 +391,7 @@ PyObject* KX_SoundActuator::PySetPitch(PyObject* self, PyObject* args, PyObject*
if (m_soundObject)
m_soundObject->SetPitch(pitch);
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -413,7 +415,7 @@ PyObject* KX_SoundActuator::PySetRollOffFactor(PyObject* self, PyObject* args, P
if (m_soundObject)
m_soundObject->SetRollOffFactor(rollofffactor);
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -437,14 +439,14 @@ PyObject* KX_SoundActuator::PySetLooping(PyObject* self, PyObject* args, PyObjec
if (m_soundObject)
m_soundObject->SetLoopMode(looping);
- Py_Return;
+ Py_RETURN_NONE;
}
PyObject* KX_SoundActuator::PyGetLooping(PyObject* self, PyObject* args, PyObject* kwds)
{
- int looping = (m_soundObject) ? m_soundObject->GetLoopMode() : SND_LOOP_OFF;
+ int looping = (m_soundObject) ? m_soundObject->GetLoopMode() : (int)SND_LOOP_OFF;
PyObject* result = PyInt_FromLong(looping);
return result;
@@ -465,7 +467,7 @@ PyObject* KX_SoundActuator::PySetPosition(PyObject* self, PyObject* args, PyObje
if (m_soundObject)
m_soundObject->SetPosition(pos);
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -483,7 +485,7 @@ PyObject* KX_SoundActuator::PySetVelocity(PyObject* self, PyObject* args, PyObje
if (m_soundObject)
m_soundObject->SetVelocity(vel);
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -507,7 +509,7 @@ PyObject* KX_SoundActuator::PySetOrientation(PyObject* self, PyObject* args, PyO
if (m_soundObject)
m_soundObject->SetOrientation(ori);
- Py_Return;
+ Py_RETURN_NONE;
}
PyObject* KX_SoundActuator::PySetType(PyObject* self, PyObject* args, PyObject* kwds)
@@ -523,7 +525,7 @@ PyObject* KX_SoundActuator::PySetType(PyObject* self, PyObject* args, PyObject*
m_type = (KX_SOUNDACT_TYPE) typeArg;
}
- Py_Return;
+ Py_RETURN_NONE;
}
PyObject* KX_SoundActuator::PyGetType(PyObject* self, PyObject* args, PyObject* kwds)
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h
index 5a9edbc4c5e..68d5b792729 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.h
+++ b/source/gameengine/Ketsji/KX_SoundActuator.h
@@ -80,7 +80,7 @@ public:
/* Python interface --------------------------------------------------- */
/* -------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
KX_PYMETHOD(KX_SoundActuator,SetFilename);
KX_PYMETHOD(KX_SoundActuator,GetFilename);
diff --git a/source/gameengine/Ketsji/KX_StateActuator.cpp b/source/gameengine/Ketsji/KX_StateActuator.cpp
index e360c4bac1f..0de4da79bd8 100644
--- a/source/gameengine/Ketsji/KX_StateActuator.cpp
+++ b/source/gameengine/Ketsji/KX_StateActuator.cpp
@@ -146,10 +146,11 @@ KX_StateActuator::Methods[] = {
{NULL,NULL} //Sentinel
};
-PyObject*
-KX_StateActuator::_getattr(
- const STR_String& attr
- )
+PyAttributeDef KX_StateActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* KX_StateActuator::_getattr(const char *attr)
{
_getattr_up(SCA_IActuator);
};
@@ -176,7 +177,7 @@ KX_StateActuator::PySetOperation(PyObject* self,
m_operation = oper;
- Py_Return;
+ Py_RETURN_NONE;
}
/* set mask ---------------------------------------------------------- */
@@ -201,7 +202,7 @@ KX_StateActuator::PySetMask(PyObject* self,
m_mask = mask;
- Py_Return;
+ Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_StateActuator.h b/source/gameengine/Ketsji/KX_StateActuator.h
index 8698e51b2c1..023b8993d7c 100644
--- a/source/gameengine/Ketsji/KX_StateActuator.h
+++ b/source/gameengine/Ketsji/KX_StateActuator.h
@@ -73,7 +73,7 @@ class KX_StateActuator : public SCA_IActuator
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
//KX_PYMETHOD_DOC
KX_PYMETHOD_DOC(KX_StateActuator,SetOperation);
KX_PYMETHOD_DOC(KX_StateActuator,SetMask);
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp
index 1935a0bde39..705b54edd37 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.cpp
+++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp
@@ -34,7 +34,9 @@
#include "SCA_LogicManager.h"
#include "KX_GameObject.h"
#include "KX_TouchEventManager.h"
-#include "KX_SumoPhysicsController.h"
+
+#include "PHY_IPhysicsController.h"
+
#include <iostream>
#include "PHY_IPhysicsEnvironment.h"
@@ -57,6 +59,7 @@ void KX_TouchSensor::EndFrame() {
m_colliders->ReleaseAndRemoveAll();
m_hitObject = NULL;
m_bTriggered = false;
+ m_bColliderHash = 0;
}
void KX_TouchSensor::UnregisterToManager()
@@ -70,7 +73,6 @@ bool KX_TouchSensor::Evaluate(CValue* event)
{
bool result = false;
bool reset = m_reset && m_level;
-
m_reset = false;
if (m_bTriggered != m_bLastTriggered)
{
@@ -82,13 +84,24 @@ bool KX_TouchSensor::Evaluate(CValue* event)
if (reset)
// force an event
result = true;
+
+ if (m_bTouchPulse) { /* pulse on changes to the colliders */
+ int count = m_colliders->GetCount();
+
+ if (m_bLastCount!=count || m_bColliderHash!=m_bLastColliderHash) {
+ m_bLastCount = count;
+ m_bLastColliderHash= m_bColliderHash;
+ result = true;
+ }
+ }
return result;
}
-KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj,bool bFindMaterial,const STR_String& touchedpropname,PyTypeObject* T)
+KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj,bool bFindMaterial,bool bTouchPulse,const STR_String& touchedpropname,PyTypeObject* T)
:SCA_ISensor(gameobj,eventmgr,T),
m_touchedpropname(touchedpropname),
m_bFindMaterial(bFindMaterial),
+m_bTouchPulse(bTouchPulse),
m_eventmgr(eventmgr)
/*m_sumoObj(sumoObj),*/
{
@@ -100,8 +113,8 @@ m_eventmgr(eventmgr)
m_colliders = new CListValue();
KX_ClientObjectInfo *client_info = gameobj->getClientInfo();
- client_info->m_gameobject = gameobj;
- client_info->m_auxilary_info = NULL;
+ //client_info->m_gameobject = gameobj;
+ //client_info->m_auxilary_info = NULL;
client_info->m_sensors.push_back(this);
m_physCtrl = dynamic_cast<PHY_IPhysicsController*>(gameobj->GetPhysicsController());
@@ -114,6 +127,8 @@ void KX_TouchSensor::Init()
m_bCollision = false;
m_bTriggered = false;
m_bLastTriggered = (m_invert)?true:false;
+ m_bLastCount = 0;
+ m_bColliderHash = m_bLastColliderHash = 0;
m_hitObject = NULL;
m_reset = true;
}
@@ -143,8 +158,8 @@ void KX_TouchSensor::ReParent(SCA_IObject* parent)
// m_solidHandle = m_sumoObj->getObjectHandle();
KX_ClientObjectInfo *client_info = gameobj->getClientInfo();
- client_info->m_gameobject = gameobj;
- client_info->m_auxilary_info = NULL;
+ //client_info->m_gameobject = gameobj;
+ //client_info->m_auxilary_info = NULL;
client_info->m_sensors.push_back(this);
SCA_ISensor::ReParent(parent);
@@ -189,8 +204,6 @@ bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_Coll
if (m_links && !m_suspended &&
gameobj && (gameobj != parent) && client_info->isActor())
{
- if (!m_colliders->SearchValue(gameobj))
- m_colliders->Add(gameobj->AddRef());
bool found = m_touchedpropname.IsEmpty();
if (!found)
@@ -199,7 +212,7 @@ bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_Coll
{
if (client_info->m_auxilary_info)
{
- found = (m_touchedpropname == STR_String((char*)client_info->m_auxilary_info));
+ found = (!strcmp(m_touchedpropname.Ptr(), (char*)client_info->m_auxilary_info));
}
} else
{
@@ -208,13 +221,19 @@ bool KX_TouchSensor::NewHandleCollision(void*object1,void*object2,const PHY_Coll
}
if (found)
{
+ if (!m_colliders->SearchValue(gameobj)) {
+ m_colliders->Add(gameobj->AddRef());
+
+ if (m_bTouchPulse)
+ m_bColliderHash += (uint_ptr)(static_cast<void *>(&gameobj));
+ }
m_bTriggered = true;
m_hitObject = gameobj;
//printf("KX_TouchSensor::HandleCollision\n");
}
}
- return DT_CONTINUE;
+ return false; // was DT_CONTINUE but this was defined in sumo as false.
}
@@ -250,21 +269,53 @@ PyParentObject KX_TouchSensor::Parents[] = {
};
PyMethodDef KX_TouchSensor::Methods[] = {
+ //Deprecated ----->
{"setProperty",
- (PyCFunction) KX_TouchSensor::sPySetProperty, METH_VARARGS, (PY_METHODCHAR)SetProperty_doc},
+ (PyCFunction) KX_TouchSensor::sPySetProperty, METH_O, (PY_METHODCHAR)SetProperty_doc},
{"getProperty",
- (PyCFunction) KX_TouchSensor::sPyGetProperty, METH_VARARGS, (PY_METHODCHAR)GetProperty_doc},
+ (PyCFunction) KX_TouchSensor::sPyGetProperty, METH_NOARGS, (PY_METHODCHAR)GetProperty_doc},
{"getHitObject",
- (PyCFunction) KX_TouchSensor::sPyGetHitObject, METH_VARARGS, (PY_METHODCHAR)GetHitObject_doc},
+ (PyCFunction) KX_TouchSensor::sPyGetHitObject, METH_NOARGS, (PY_METHODCHAR)GetHitObject_doc},
{"getHitObjectList",
- (PyCFunction) KX_TouchSensor::sPyGetHitObjectList, METH_VARARGS, (PY_METHODCHAR)GetHitObjectList_doc},
+ (PyCFunction) KX_TouchSensor::sPyGetHitObjectList, METH_NOARGS, (PY_METHODCHAR)GetHitObjectList_doc},
+ //<-----
{NULL,NULL} //Sentinel
};
-PyObject* KX_TouchSensor::_getattr(const STR_String& attr) {
+PyAttributeDef KX_TouchSensor::Attributes[] = {
+ KX_PYATTRIBUTE_STRING_RW("property",0,100,false,KX_TouchSensor,m_touchedpropname),
+ KX_PYATTRIBUTE_BOOL_RW("useMaterial",KX_TouchSensor,m_bFindMaterial),
+ KX_PYATTRIBUTE_BOOL_RW("pulseCollisions",KX_TouchSensor,m_bTouchPulse),
+ KX_PYATTRIBUTE_DUMMY("objectHit"),
+ KX_PYATTRIBUTE_DUMMY("objectHitList"),
+ { NULL } //Sentinel
+};
+
+PyObject* KX_TouchSensor::_getattr(const char *attr)
+{
+ if (!strcmp(attr, "objectHit")) {
+ if (m_hitObject) return m_hitObject->AddRef();
+ else Py_RETURN_NONE;
+ }
+ if (!strcmp(attr, "objectHitList")) {
+ return m_colliders->AddRef();
+ }
+
+ PyObject* object= _getattr_self(Attributes, this, attr);
+ if (object != NULL)
+ return object;
_getattr_up(SCA_ISensor);
}
+int KX_TouchSensor::_setattr(const char *attr, PyObject *value)
+{
+ int ret = _setattr_self(Attributes, this, attr, value);
+ if (ret >= 0)
+ return ret;
+
+ return SCA_ISensor::_setattr(attr, value);
+}
+
/* Python API */
/* 1. setProperty */
@@ -274,24 +325,17 @@ const char KX_TouchSensor::SetProperty_doc[] =
"\tSet the property or material to collide with. Use\n"
"\tsetTouchMaterial() to switch between properties and\n"
"\tmaterials.";
-PyObject* KX_TouchSensor::PySetProperty(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
- char *nameArg;
- if (!PyArg_ParseTuple(args, "s", &nameArg)) {
+PyObject* KX_TouchSensor::PySetProperty(PyObject* self, PyObject* value)
+{
+ ShowDeprecationWarning("setProperty()", "the propertyName property");
+ char *nameArg= PyString_AsString(value);
+ if (nameArg==NULL) {
+ PyErr_SetString(PyExc_ValueError, "expected a ");
return NULL;
}
-
- CValue* prop = GetParent()->FindIdentifier(nameArg);
-
- if (!prop->IsError()) {
- m_touchedpropname = nameArg;
- } else {
- ; /* not found ... */
- }
- prop->Release();
- Py_Return;
+ m_touchedpropname = nameArg;
+ Py_RETURN_NONE;
}
/* 2. getProperty */
const char KX_TouchSensor::GetProperty_doc[] =
@@ -299,111 +343,71 @@ const char KX_TouchSensor::GetProperty_doc[] =
"\tReturns the property or material to collide with. Use\n"
"\tgetTouchMaterial() to find out whether this sensor\n"
"\tlooks for properties or materials.";
-PyObject* KX_TouchSensor::PyGetProperty(PyObject* self,
- PyObject* args,
- PyObject* kwds) {
+PyObject* KX_TouchSensor::PyGetProperty(PyObject* self) {
return PyString_FromString(m_touchedpropname);
}
const char KX_TouchSensor::GetHitObject_doc[] =
"getHitObject()\n"
;
-PyObject* KX_TouchSensor::PyGetHitObject(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_TouchSensor::PyGetHitObject(PyObject* self)
{
+ ShowDeprecationWarning("getHitObject()", "the objectHit property");
/* to do: do Py_IncRef if the object is already known in Python */
/* otherwise, this leaks memory */
if (m_hitObject)
{
return m_hitObject->AddRef();
}
- Py_Return;
+ Py_RETURN_NONE;
}
const char KX_TouchSensor::GetHitObjectList_doc[] =
"getHitObjectList()\n"
"\tReturn a list of the objects this object collided with,\n"
"\tbut only those matching the property/material condition.\n";
-PyObject* KX_TouchSensor::PyGetHitObjectList(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_TouchSensor::PyGetHitObjectList(PyObject* self)
{
-
+ ShowDeprecationWarning("getHitObjectList()", "the objectHitList property");
/* to do: do Py_IncRef if the object is already known in Python */
- /* otherwise, this leaks memory */
-
- if ( m_touchedpropname.IsEmpty() ) {
- return m_colliders->AddRef();
- } else {
- CListValue* newList = new CListValue();
- int i = 0;
- while (i < m_colliders->GetCount()) {
- if (m_bFindMaterial) {
- /* need to associate the CValues from the list to material
- * names. The collider list _should_ contains only
- * KX_GameObjects. I am loathe to cast them, though... The
- * material name must be retrieved from Sumo. To a Sumo
- * object, a client-info block is attached. This block
- * contains the material name.
- * - this also doesn't work (obviously) for multi-materials...
- */
- KX_GameObject* gameob = (KX_GameObject*) m_colliders->GetValue(i);
- PHY_IPhysicsController* spc = dynamic_cast<PHY_IPhysicsController*>(gameob->GetPhysicsController());
-
- if (spc) {
- KX_ClientObjectInfo* cl_inf = static_cast<KX_ClientObjectInfo*>(spc->getNewClientInfo());
-
- if (m_touchedpropname == ((char*)cl_inf->m_auxilary_info)) {
- newList->Add(m_colliders->GetValue(i)->AddRef());
- }
- }
-
- } else {
- CValue* val = m_colliders->GetValue(i)->FindIdentifier(m_touchedpropname);
- if (!val->IsError()) {
- newList->Add(m_colliders->GetValue(i)->AddRef());
- }
- val->Release();
- }
-
- i++;
- }
- return newList->AddRef();
- }
-
+ /* otherwise, this leaks memory */ /* Edit, this seems ok and not to leak memory - Campbell */
+ return m_colliders->AddRef();
}
+/*getTouchMaterial and setTouchMaterial were never added to the api,
+they can probably be removed with out anyone noticing*/
+
/* 5. getTouchMaterial */
const char KX_TouchSensor::GetTouchMaterial_doc[] =
"getTouchMaterial()\n"
"\tReturns KX_TRUE if this sensor looks for a specific material,\n"
"\tKX_FALSE if it looks for a specific property.\n" ;
-PyObject* KX_TouchSensor::PyGetTouchMaterial(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+PyObject* KX_TouchSensor::PyGetTouchMaterial(PyObject* self)
{
+ ShowDeprecationWarning("getTouchMaterial()", "the materialCheck property");
return PyInt_FromLong(m_bFindMaterial);
}
/* 6. setTouchMaterial */
+#if 0
const char KX_TouchSensor::SetTouchMaterial_doc[] =
"setTouchMaterial(flag)\n"
"\t- flag: KX_TRUE or KX_FALSE.\n"
"\tSet flag to KX_TRUE to switch on positive pulse mode,\n"
"\tKX_FALSE to switch off positive pulse mode.\n" ;
-PyObject* KX_TouchSensor::PySetTouchMaterial(PyObject* self, PyObject* args, PyObject* kwds)
+PyObject* KX_TouchSensor::PySetTouchMaterial(PyObject* self, PyObject *value)
{
- int pulseArg = 0;
+ int pulseArg = PyInt_AsLong(value);
- if(!PyArg_ParseTuple(args, "i", &pulseArg)) {
+ if(pulseArg ==-1 && PyErr_Occurred()) {
+ PyErr_SetString(PyExc_ValueError, "expected a bool");
return NULL;
}
m_bFindMaterial = pulseArg != 0;
- Py_Return;
+ Py_RETURN_NONE;
}
-
+#endif
/* eof */
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h
index 8fbb1c676ba..18ce9406a9b 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.h
+++ b/source/gameengine/Ketsji/KX_TouchSensor.h
@@ -39,6 +39,12 @@ struct PHY_CollData;
#include "KX_ClientObjectInfo.h"
+#if defined(_WIN64)
+typedef unsigned __int64 uint_ptr;
+#else
+typedef unsigned long uint_ptr;
+#endif
+
class KX_TouchEventManager;
class KX_TouchSensor : public SCA_ISensor
@@ -51,6 +57,7 @@ protected:
*/
STR_String m_touchedpropname;
bool m_bFindMaterial;
+ bool m_bTouchPulse; /* changes in the colliding objects trigger pulses */
class SCA_EventManager* m_eventmgr;
class PHY_IPhysicsController* m_physCtrl;
@@ -58,13 +65,20 @@ protected:
bool m_bCollision;
bool m_bTriggered;
bool m_bLastTriggered;
+
+ // Use with m_bTouchPulse to detect changes
+ int m_bLastCount; /* size of m_colliders last tick */
+ uint_ptr m_bColliderHash; /* hash collision objects pointers to trigger incase one object collides and another takes its place */
+ uint_ptr m_bLastColliderHash;
+
SCA_IObject* m_hitObject;
class CListValue* m_colliders;
public:
KX_TouchSensor(class SCA_EventManager* eventmgr,
class KX_GameObject* gameobj,
- bool fFindMaterial,
+ bool bFindMaterial,
+ bool bTouchPulse,
const STR_String& touchedpropname,
PyTypeObject* T=&Type) ;
virtual ~KX_TouchSensor();
@@ -106,20 +120,25 @@ public:
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
+ //Deprecated ----->
/* 1. setProperty */
- KX_PYMETHOD_DOC(KX_TouchSensor,SetProperty);
+ KX_PYMETHOD_DOC_O(KX_TouchSensor,SetProperty);
/* 2. getProperty */
- KX_PYMETHOD_DOC(KX_TouchSensor,GetProperty);
+ KX_PYMETHOD_DOC_NOARGS(KX_TouchSensor,GetProperty);
/* 3. getHitObject */
- KX_PYMETHOD_DOC(KX_TouchSensor,GetHitObject);
+ KX_PYMETHOD_DOC_NOARGS(KX_TouchSensor,GetHitObject);
/* 4. getHitObject */
- KX_PYMETHOD_DOC(KX_TouchSensor,GetHitObjectList);
+ KX_PYMETHOD_DOC_NOARGS(KX_TouchSensor,GetHitObjectList);
/* 5. getTouchMaterial */
- KX_PYMETHOD_DOC(KX_TouchSensor,GetTouchMaterial);
+ KX_PYMETHOD_DOC_NOARGS(KX_TouchSensor,GetTouchMaterial);
+#if 0
/* 6. setTouchMaterial */
- KX_PYMETHOD_DOC(KX_TouchSensor,SetTouchMaterial);
+ KX_PYMETHOD_DOC_O(KX_TouchSensor,SetTouchMaterial);
+#endif
+ //<-----
};
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
index acc4a6ab5d7..8637bc92d39 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
@@ -258,18 +258,18 @@ bool KX_TrackToActuator::Update(double curtime, bool frame)
{
case 0:
{
- up = MT_Vector3(1.0,0,0);
+ up.setValue(1.0,0,0);
break;
}
case 1:
{
- up = MT_Vector3(0,1.0,0);
+ up.setValue(0,1.0,0);
break;
}
case 2:
default:
{
- up = MT_Vector3(0,0,1.0);
+ up.setValue(0,0,1.0);
}
}
#endif
@@ -456,23 +456,54 @@ PyParentObject KX_TrackToActuator::Parents[] = {
PyMethodDef KX_TrackToActuator::Methods[] = {
- {"setObject", (PyCFunction) KX_TrackToActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc},
- {"getObject", (PyCFunction) KX_TrackToActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc},
{"setTime", (PyCFunction) KX_TrackToActuator::sPySetTime, METH_VARARGS, (PY_METHODCHAR)SetTime_doc},
{"getTime", (PyCFunction) KX_TrackToActuator::sPyGetTime, METH_VARARGS, (PY_METHODCHAR)GetTime_doc},
{"setUse3D", (PyCFunction) KX_TrackToActuator::sPySetUse3D, METH_VARARGS, (PY_METHODCHAR)SetUse3D_doc},
{"getUse3D", (PyCFunction) KX_TrackToActuator::sPyGetUse3D, METH_VARARGS, (PY_METHODCHAR)GetUse3D_doc},
+
+ // ---> deprecated
+ {"setObject", (PyCFunction) KX_TrackToActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc},
+ {"getObject", (PyCFunction) KX_TrackToActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc},
+
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_TrackToActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
-PyObject* KX_TrackToActuator::_getattr(const STR_String& attr)
+PyObject* KX_TrackToActuator::_getattr(const char *attr)
{
+ if (!strcmp(attr, "object")) {
+ if (!m_object) Py_RETURN_NONE;
+ else return m_object->AddRef();
+ }
+
_getattr_up(SCA_IActuator);
}
+int KX_TrackToActuator::_setattr(const char *attr, PyObject* value)
+{
+ if (!strcmp(attr, "object")) {
+ KX_GameObject *gameobj;
+
+ if (!ConvertPythonToGameObject(value, &gameobj, true))
+ return 1; // ConvertPythonToGameObject sets the error
+
+ if (m_object != NULL)
+ m_object->UnregisterActuator(this);
+ m_object = (SCA_IObject*)gameobj;
+
+ if (m_object)
+ m_object->RegisterActuator(this);
+
+ return 0;
+ }
+
+ return SCA_IActuator::_setattr(attr, value);
+}
/* 1. setObject */
const char KX_TrackToActuator::SetObject_doc[] =
@@ -483,6 +514,8 @@ PyObject* KX_TrackToActuator::PySetObject(PyObject* self, PyObject* value)
{
KX_GameObject *gameobj;
+ ShowDeprecationWarning("setObject()", "the object property");
+
if (!ConvertPythonToGameObject(value, &gameobj, true))
return NULL; // ConvertPythonToGameObject sets the error
@@ -506,6 +539,9 @@ const char KX_TrackToActuator::GetObject_doc[] =
PyObject* KX_TrackToActuator::PyGetObject(PyObject* self, PyObject* args)
{
int ret_name_only = 1;
+
+ ShowDeprecationWarning("getObject()", "the object property");
+
if (!PyArg_ParseTuple(args, "|i", &ret_name_only))
return NULL;
@@ -536,7 +572,7 @@ PyObject* KX_TrackToActuator::PySetTime(PyObject* self, PyObject* args, PyObject
m_time= timeArg;
- Py_Return;
+ Py_RETURN_NONE;
}
@@ -580,7 +616,7 @@ PyObject* KX_TrackToActuator::PySetUse3D(PyObject* self, PyObject* args, PyObjec
m_allow3D = !(boolArg == 0);
- Py_Return;
+ Py_RETURN_NONE;
}
/* eof */
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h
index 445132a6094..392e55402f1 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.h
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.h
@@ -72,7 +72,8 @@ class KX_TrackToActuator : public SCA_IActuator
virtual bool Update(double curtime, bool frame);
/* Python part */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject* value);
/* 1. setObject */
KX_PYMETHOD_DOC_O(KX_TrackToActuator,SetObject);
diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
index 028f96f6c5b..8d5af1b9216 100644
--- a/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
+++ b/source/gameengine/Ketsji/KX_VehicleWrapper.cpp
@@ -322,13 +322,13 @@ PyParentObject KX_VehicleWrapper::Parents[] = {
NULL
};
-PyObject* KX_VehicleWrapper::_getattr(const STR_String& attr)
+PyObject* KX_VehicleWrapper::_getattr(const char *attr)
{
//here you can search for existing data members (like mass,friction etc.)
_getattr_up(PyObjectPlus);
}
-int KX_VehicleWrapper::_setattr(const STR_String& attr,PyObject* pyobj)
+int KX_VehicleWrapper::_setattr(const char *attr,PyObject* pyobj)
{
PyTypeObject* type = pyobj->ob_type;
@@ -382,3 +382,6 @@ PyMethodDef KX_VehicleWrapper::Methods[] = {
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_VehicleWrapper::Attributes[] = {
+ { NULL } //Sentinel
+};
diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.h b/source/gameengine/Ketsji/KX_VehicleWrapper.h
index b98369d401a..cad926ce85a 100644
--- a/source/gameengine/Ketsji/KX_VehicleWrapper.h
+++ b/source/gameengine/Ketsji/KX_VehicleWrapper.h
@@ -12,8 +12,8 @@ class PHY_IMotionState;
class KX_VehicleWrapper : public PyObjectPlus
{
Py_Header;
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *value);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *value);
std::vector<PHY_IMotionState*> m_motionStates;
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.cpp b/source/gameengine/Ketsji/KX_VertexProxy.cpp
index 25205714308..da0e3dbdd8d 100644
--- a/source/gameengine/Ketsji/KX_VertexProxy.cpp
+++ b/source/gameengine/Ketsji/KX_VertexProxy.cpp
@@ -63,31 +63,63 @@ PyParentObject KX_VertexProxy::Parents[] = {
};
PyMethodDef KX_VertexProxy::Methods[] = {
-{"getXYZ", (PyCFunction)KX_VertexProxy::sPyGetXYZ,METH_VARARGS},
-{"setXYZ", (PyCFunction)KX_VertexProxy::sPySetXYZ,METH_VARARGS},
-{"getUV", (PyCFunction)KX_VertexProxy::sPyGetUV,METH_VARARGS},
-{"setUV", (PyCFunction)KX_VertexProxy::sPySetUV,METH_VARARGS},
+{"getXYZ", (PyCFunction)KX_VertexProxy::sPyGetXYZ,METH_NOARGS},
+{"setXYZ", (PyCFunction)KX_VertexProxy::sPySetXYZ,METH_O},
+{"getUV", (PyCFunction)KX_VertexProxy::sPyGetUV,METH_NOARGS},
+{"setUV", (PyCFunction)KX_VertexProxy::sPySetUV,METH_O},
-{"getUV2", (PyCFunction)KX_VertexProxy::sPyGetUV2,METH_VARARGS},
+{"getUV2", (PyCFunction)KX_VertexProxy::sPyGetUV2,METH_NOARGS},
{"setUV2", (PyCFunction)KX_VertexProxy::sPySetUV2,METH_VARARGS},
-{"getRGBA", (PyCFunction)KX_VertexProxy::sPyGetRGBA,METH_VARARGS},
-{"setRGBA", (PyCFunction)KX_VertexProxy::sPySetRGBA,METH_VARARGS},
-{"getNormal", (PyCFunction)KX_VertexProxy::sPyGetNormal,METH_VARARGS},
-{"setNormal", (PyCFunction)KX_VertexProxy::sPySetNormal,METH_VARARGS},
+{"getRGBA", (PyCFunction)KX_VertexProxy::sPyGetRGBA,METH_NOARGS},
+{"setRGBA", (PyCFunction)KX_VertexProxy::sPySetRGBA,METH_O},
+{"getNormal", (PyCFunction)KX_VertexProxy::sPyGetNormal,METH_NOARGS},
+{"setNormal", (PyCFunction)KX_VertexProxy::sPySetNormal,METH_O},
{NULL,NULL} //Sentinel
};
+PyAttributeDef KX_VertexProxy::Attributes[] = {
+ { NULL } //Sentinel
+};
+
PyObject*
-KX_VertexProxy::_getattr(const STR_String& attr)
+KX_VertexProxy::_getattr(const char *attr)
{
- if (attr == "XYZ")
+
+ if (attr[1]=='\0') { // Group single letters
+ // pos
+ if (attr[0]=='x')
+ return PyFloat_FromDouble(m_vertex->getXYZ()[0]);
+ if (attr[0]=='y')
+ return PyFloat_FromDouble(m_vertex->getXYZ()[1]);
+ if (attr[0]=='z')
+ return PyFloat_FromDouble(m_vertex->getXYZ()[2]);
+
+ // Col
+ if (attr[0]=='r')
+ return PyFloat_FromDouble(m_vertex->getRGBA()[0]/255.0);
+ if (attr[0]=='g')
+ return PyFloat_FromDouble(m_vertex->getRGBA()[1]/255.0);
+ if (attr[0]=='b')
+ return PyFloat_FromDouble(m_vertex->getRGBA()[2]/255.0);
+ if (attr[0]=='a')
+ return PyFloat_FromDouble(m_vertex->getRGBA()[3]/255.0);
+
+ // UV
+ if (attr[0]=='u')
+ return PyFloat_FromDouble(m_vertex->getUV1()[0]);
+ if (attr[0]=='v')
+ return PyFloat_FromDouble(m_vertex->getUV1()[1]);
+ }
+
+
+ if (!strcmp(attr, "XYZ"))
return PyObjectFrom(MT_Vector3(m_vertex->getXYZ()));
- if (attr == "UV")
+ if (!strcmp(attr, "UV"))
return PyObjectFrom(MT_Point2(m_vertex->getUV1()));
- if (attr == "colour" || attr == "color")
+ if (!strcmp(attr, "color") || !strcmp(attr, "colour"))
{
const unsigned char *colp = m_vertex->getRGBA();
MT_Vector4 color(colp[0], colp[1], colp[2], colp[3]);
@@ -95,43 +127,19 @@ KX_VertexProxy::_getattr(const STR_String& attr)
return PyObjectFrom(color);
}
- if (attr == "normal")
+ if (!strcmp(attr, "normal"))
{
return PyObjectFrom(MT_Vector3(m_vertex->getNormal()));
}
-
- // pos
- if (attr == "x")
- return PyFloat_FromDouble(m_vertex->getXYZ()[0]);
- if (attr == "y")
- return PyFloat_FromDouble(m_vertex->getXYZ()[1]);
- if (attr == "z")
- return PyFloat_FromDouble(m_vertex->getXYZ()[2]);
-
- // Col
- if (attr == "r")
- return PyFloat_FromDouble(m_vertex->getRGBA()[0]/255.0);
- if (attr == "g")
- return PyFloat_FromDouble(m_vertex->getRGBA()[1]/255.0);
- if (attr == "b")
- return PyFloat_FromDouble(m_vertex->getRGBA()[2]/255.0);
- if (attr == "a")
- return PyFloat_FromDouble(m_vertex->getRGBA()[3]/255.0);
-
- // UV
- if (attr == "u")
- return PyFloat_FromDouble(m_vertex->getUV1()[0]);
- if (attr == "v")
- return PyFloat_FromDouble(m_vertex->getUV1()[1]);
-
+
_getattr_up(SCA_IObject);
}
-int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue)
+int KX_VertexProxy::_setattr(const char *attr, PyObject *pyvalue)
{
if (PySequence_Check(pyvalue))
{
- if (attr == "XYZ")
+ if (!strcmp(attr, "XYZ"))
{
MT_Point3 vec;
if (PyVecTo(pyvalue, vec))
@@ -143,7 +151,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue)
return 1;
}
- if (attr == "UV")
+ if (!strcmp(attr, "UV"))
{
MT_Point2 vec;
if (PyVecTo(pyvalue, vec))
@@ -155,7 +163,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue)
return 1;
}
- if (attr == "colour" || attr == "color")
+ if (!strcmp(attr, "color") || !strcmp(attr, "colour"))
{
MT_Vector4 vec;
if (PyVecTo(pyvalue, vec))
@@ -167,7 +175,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue)
return 1;
}
- if (attr == "normal")
+ if (!strcmp(attr, "normal"))
{
MT_Vector3 vec;
if (PyVecTo(pyvalue, vec))
@@ -185,7 +193,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue)
float val = PyFloat_AsDouble(pyvalue);
// pos
MT_Point3 pos(m_vertex->getXYZ());
- if (attr == "x")
+ if (!strcmp(attr, "x"))
{
pos.x() = val;
m_vertex->SetXYZ(pos);
@@ -193,7 +201,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue)
return 0;
}
- if (attr == "y")
+ if (!strcmp(attr, "y"))
{
pos.y() = val;
m_vertex->SetXYZ(pos);
@@ -201,7 +209,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue)
return 0;
}
- if (attr == "z")
+ if (!strcmp(attr, "z"))
{
pos.z() = val;
m_vertex->SetXYZ(pos);
@@ -211,7 +219,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue)
// uv
MT_Point2 uv = m_vertex->getUV1();
- if (attr == "u")
+ if (!strcmp(attr, "u"))
{
uv[0] = val;
m_vertex->SetUV(uv);
@@ -219,7 +227,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue)
return 0;
}
- if (attr == "v")
+ if (!strcmp(attr, "v"))
{
uv[1] = val;
m_vertex->SetUV(uv);
@@ -229,7 +237,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue)
// uv
MT_Point2 uv2 = m_vertex->getUV2();
- if (attr == "u2")
+ if (!strcmp(attr, "u2"))
{
uv[0] = val;
m_vertex->SetUV2(uv);
@@ -237,7 +245,7 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue)
return 0;
}
- if (attr == "v2")
+ if (!strcmp(attr, "v2"))
{
uv[1] = val;
m_vertex->SetUV2(uv);
@@ -249,28 +257,28 @@ int KX_VertexProxy::_setattr(const STR_String& attr, PyObject *pyvalue)
unsigned int icol = *((const unsigned int *)m_vertex->getRGBA());
unsigned char *cp = (unsigned char*) &icol;
val *= 255.0;
- if (attr == "r")
+ if (!strcmp(attr, "r"))
{
cp[0] = (unsigned char) val;
m_vertex->SetRGBA(icol);
m_mesh->SetMeshModified(true);
return 0;
}
- if (attr == "g")
+ if (!strcmp(attr, "g"))
{
cp[1] = (unsigned char) val;
m_vertex->SetRGBA(icol);
m_mesh->SetMeshModified(true);
return 0;
}
- if (attr == "b")
+ if (!strcmp(attr, "b"))
{
cp[2] = (unsigned char) val;
m_vertex->SetRGBA(icol);
m_mesh->SetMeshModified(true);
return 0;
}
- if (attr == "a")
+ if (!strcmp(attr, "a"))
{
cp[3] = (unsigned char) val;
m_vertex->SetRGBA(icol);
@@ -308,130 +316,103 @@ void KX_VertexProxy::ReplicaSetName(STR_String) {};
// stuff for python integration
-PyObject* KX_VertexProxy::PyGetXYZ(PyObject*,
- PyObject*,
- PyObject*)
+PyObject* KX_VertexProxy::PyGetXYZ(PyObject*)
{
return PyObjectFrom(MT_Point3(m_vertex->getXYZ()));
}
-PyObject* KX_VertexProxy::PySetXYZ(PyObject*,
- PyObject* args,
- PyObject*)
+PyObject* KX_VertexProxy::PySetXYZ(PyObject*, PyObject* value)
{
MT_Point3 vec;
- if (PyVecArgTo(args, vec))
- {
- m_vertex->SetXYZ(vec);
- m_mesh->SetMeshModified(true);
- Py_Return;
- }
-
- return NULL;
+ if (!PyVecTo(value, vec))
+ return NULL;
+
+ m_vertex->SetXYZ(vec);
+ m_mesh->SetMeshModified(true);
+ Py_RETURN_NONE;
}
-PyObject* KX_VertexProxy::PyGetNormal(PyObject*,
- PyObject*,
- PyObject*)
+PyObject* KX_VertexProxy::PyGetNormal(PyObject*)
{
return PyObjectFrom(MT_Vector3(m_vertex->getNormal()));
}
-PyObject* KX_VertexProxy::PySetNormal(PyObject*,
- PyObject* args,
- PyObject*)
+PyObject* KX_VertexProxy::PySetNormal(PyObject*, PyObject* value)
{
MT_Vector3 vec;
- if (PyVecArgTo(args, vec))
- {
- m_vertex->SetNormal(vec);
- m_mesh->SetMeshModified(true);
- Py_Return;
- }
+ if (!PyVecTo(value, vec))
+ return NULL;
- return NULL;
+ m_vertex->SetNormal(vec);
+ m_mesh->SetMeshModified(true);
+ Py_RETURN_NONE;
}
-PyObject* KX_VertexProxy::PyGetRGBA(PyObject*,
- PyObject*,
- PyObject*)
+PyObject* KX_VertexProxy::PyGetRGBA(PyObject*)
{
int *rgba = (int *) m_vertex->getRGBA();
return PyInt_FromLong(*rgba);
}
-PyObject* KX_VertexProxy::PySetRGBA(PyObject*,
- PyObject* args,
- PyObject*)
+PyObject* KX_VertexProxy::PySetRGBA(PyObject*, PyObject* value)
{
- float r, g, b, a;
- if (PyArg_ParseTuple(args, "(ffff)", &r, &g, &b, &a))
- {
- m_vertex->SetRGBA(MT_Vector4(r, g, b, a));
- m_mesh->SetMeshModified(true);
- Py_Return;
- }
- PyErr_Clear();
-
- int rgba;
- if (PyArg_ParseTuple(args,"i",&rgba))
- {
+ if PyInt_Check(value) {
+ int rgba = PyInt_AsLong(value);
m_vertex->SetRGBA(rgba);
m_mesh->SetMeshModified(true);
- Py_Return;
+ Py_RETURN_NONE;
+ }
+ else {
+ MT_Vector4 vec;
+ if (PyVecTo(value, vec))
+ {
+ m_vertex->SetRGBA(vec);
+ m_mesh->SetMeshModified(true);
+ Py_RETURN_NONE;
+ }
}
+ PyErr_SetString(PyExc_TypeError, "expected a 4D vector or an int");
return NULL;
}
-PyObject* KX_VertexProxy::PyGetUV(PyObject*,
- PyObject*,
- PyObject*)
+PyObject* KX_VertexProxy::PyGetUV(PyObject*)
{
return PyObjectFrom(MT_Vector2(m_vertex->getUV1()));
}
-PyObject* KX_VertexProxy::PySetUV(PyObject*,
- PyObject* args,
- PyObject*)
+PyObject* KX_VertexProxy::PySetUV(PyObject*, PyObject* value)
{
MT_Point2 vec;
- if (PyVecArgTo(args, vec))
- {
- m_vertex->SetUV(vec);
- m_mesh->SetMeshModified(true);
- Py_Return;
- }
+ if (!PyVecTo(value, vec))
+ return NULL;
- return NULL;
+ m_vertex->SetUV(vec);
+ m_mesh->SetMeshModified(true);
+ Py_RETURN_NONE;
}
-PyObject* KX_VertexProxy::PyGetUV2(PyObject*,
- PyObject*,
- PyObject*)
+PyObject* KX_VertexProxy::PyGetUV2(PyObject*)
{
return PyObjectFrom(MT_Vector2(m_vertex->getUV2()));
}
-PyObject* KX_VertexProxy::PySetUV2(PyObject*,
- PyObject* args,
- PyObject*)
+PyObject* KX_VertexProxy::PySetUV2(PyObject*, PyObject* args)
{
MT_Point2 vec;
unsigned int unit=0;
- PyObject* list=0;
- if(PyArg_ParseTuple(args, "Oi", &list, &unit))
- {
- if (PyVecTo(list, vec))
- {
- m_vertex->SetFlag((m_vertex->getFlag()|RAS_TexVert::SECOND_UV));
- m_vertex->SetUnit(unit);
- m_vertex->SetUV2(vec);
- m_mesh->SetMeshModified(true);
- Py_Return;
- }
- }
- return NULL;
+ PyObject* list= NULL;
+ if(!PyArg_ParseTuple(args, "Oi:setUV2", &list, &unit))
+ return NULL;
+
+ if (!PyVecTo(list, vec))
+ return NULL;
+
+ m_vertex->SetFlag((m_vertex->getFlag()|RAS_TexVert::SECOND_UV));
+ m_vertex->SetUnit(unit);
+ m_vertex->SetUV2(vec);
+ m_mesh->SetMeshModified(true);
+ Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h
index e154ea11b40..28196075904 100644
--- a/source/gameengine/Ketsji/KX_VertexProxy.h
+++ b/source/gameengine/Ketsji/KX_VertexProxy.h
@@ -54,21 +54,21 @@ public:
// stuff for python integration
- virtual PyObject* _getattr(const STR_String& attr);
- virtual int _setattr(const STR_String& attr, PyObject *pyvalue);
+ virtual PyObject* _getattr(const char *attr);
+ virtual int _setattr(const char *attr, PyObject *pyvalue);
- KX_PYMETHOD(KX_VertexProxy,GetXYZ);
- KX_PYMETHOD(KX_VertexProxy,SetXYZ);
- KX_PYMETHOD(KX_VertexProxy,GetUV);
- KX_PYMETHOD(KX_VertexProxy,SetUV);
+ KX_PYMETHOD_NOARGS(KX_VertexProxy,GetXYZ);
+ KX_PYMETHOD_O(KX_VertexProxy,SetXYZ);
+ KX_PYMETHOD_NOARGS(KX_VertexProxy,GetUV);
+ KX_PYMETHOD_O(KX_VertexProxy,SetUV);
- KX_PYMETHOD(KX_VertexProxy,GetUV2);
- KX_PYMETHOD(KX_VertexProxy,SetUV2);
+ KX_PYMETHOD_NOARGS(KX_VertexProxy,GetUV2);
+ KX_PYMETHOD_VARARGS(KX_VertexProxy,SetUV2);
- KX_PYMETHOD(KX_VertexProxy,GetRGBA);
- KX_PYMETHOD(KX_VertexProxy,SetRGBA);
- KX_PYMETHOD(KX_VertexProxy,GetNormal);
- KX_PYMETHOD(KX_VertexProxy,SetNormal);
+ KX_PYMETHOD_NOARGS(KX_VertexProxy,GetRGBA);
+ KX_PYMETHOD_O(KX_VertexProxy,SetRGBA);
+ KX_PYMETHOD_NOARGS(KX_VertexProxy,GetNormal);
+ KX_PYMETHOD_O(KX_VertexProxy,SetNormal);
};
diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
index 4b0db5a7953..0ec280080bd 100644
--- a/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
+++ b/source/gameengine/Ketsji/KX_VisibilityActuator.cpp
@@ -126,10 +126,11 @@ KX_VisibilityActuator::Methods[] = {
{NULL,NULL} //Sentinel
};
-PyObject*
-KX_VisibilityActuator::_getattr(
- const STR_String& attr
- )
+PyAttributeDef KX_VisibilityActuator::Attributes[] = {
+ { NULL } //Sentinel
+};
+
+PyObject* KX_VisibilityActuator::_getattr(const char *attr)
{
_getattr_up(SCA_IActuator);
};
@@ -155,7 +156,7 @@ KX_VisibilityActuator::PySetVisible(PyObject* self,
m_visible = PyArgToBool(vis);
- Py_Return;
+ Py_RETURN_NONE;
}
diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.h b/source/gameengine/Ketsji/KX_VisibilityActuator.h
index d1b85ab998c..323280de8cb 100644
--- a/source/gameengine/Ketsji/KX_VisibilityActuator.h
+++ b/source/gameengine/Ketsji/KX_VisibilityActuator.h
@@ -67,7 +67,7 @@ class KX_VisibilityActuator : public SCA_IActuator
/* Python interface ---------------------------------------------------- */
/* --------------------------------------------------------------------- */
- virtual PyObject* _getattr(const STR_String& attr);
+ virtual PyObject* _getattr(const char *attr);
//KX_PYMETHOD_DOC
KX_PYMETHOD_DOC(KX_VisibilityActuator,SetVisible);
diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript
index 13a0d321cff..950c82b2795 100644
--- a/source/gameengine/Ketsji/SConscript
+++ b/source/gameengine/Ketsji/SConscript
@@ -4,6 +4,7 @@ import sys
Import ('env')
sources = env.Glob('*.cpp')
+defs = ''
#XXX
# Mathutils C files.
@@ -31,21 +32,27 @@ incs += ' #source/blender/makesdna #source/blender/python #source/gameengine/Ras
incs += ' #source/gameengine/GameLogic #source/gameengine/Expressions #source/gameengine/Network'
incs += ' #source/gameengine/SceneGraph #source/gameengine/Physics/common #source/gameengine/Physics/Bullet'
incs += ' #source/gameengine/Physics/BlOde #source/gameengine/Physics/Dummy'
-incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/include'
-incs += ' #source/gameengine/Physics/Sumo/Fuzzics/include #source/gameengine/Network/LoopBackNetwork'
incs += ' #source/blender/misc #source/blender/blenloader #extern/glew/include #source/blender/gpu'
-cflags = []
-if env['OURPLATFORM'] == 'win32-vc':
- cflags.append('/GR')
- cflags.append('/Ox')
+if env['WITH_BF_SOLID']:
+ incs += ' #source/gameengine/Physics/Sumo #source/gameengine/Physics/Sumo/include'
+ incs += ' #source/gameengine/Physics/Sumo/Fuzzics/include #source/gameengine/Network/LoopBackNetwork'
+ incs += ' ' + env['BF_SOLID_INC']
+ defs += ' USE_SUMO_SOLID'
+
-incs += ' ' + env['BF_SOLID_INC']
incs += ' ' + env['BF_PYTHON_INC']
incs += ' ' + env['BF_BULLET_INC']
incs += ' ' + env['BF_OPENGL_INC']
if env['WITH_BF_SDL']:
incs += ' ' + env['BF_SDL_INC']
-
-env.BlenderLib ( 'bf_ketsji', sources, Split(incs), [], libtype=['core','player'], priority=[320, 60], compileflags = cflags )
+else:
+ defs += ' DISABLE_SDL'
+
+cxxflags = []
+if env['OURPLATFORM']=='win32-vc':
+ cxxflags.append ('/GR')
+ cxxflags.append ('/O2')
+
+env.BlenderLib ( 'bf_ketsji', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[320, 60], cxx_compileflags = cxxflags )
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index d09ad58fe3b..eecdea55349 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -1240,7 +1240,7 @@ void DefaultMotionState::getWorldOrientation(float& quatIma0,float& quatIma1,flo
void DefaultMotionState::setWorldPosition(float posX,float posY,float posZ)
{
- btPoint3 pos(posX,posY,posZ);
+ btVector3 pos(posX,posY,posZ);
m_worldTransform.setOrigin( pos );
}
@@ -1328,7 +1328,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo
for (int i=0;i<poly->VertexCount();i++)
{
const float* vtx = poly->GetVertex(i)->getXYZ();
- btPoint3 point(vtx[0],vtx[1],vtx[2]);
+ btVector3 point(vtx[0],vtx[1],vtx[2]);
//avoid duplicates (could better directly use vertex offsets, rather than a vertex compare)
bool found = false;
for (int j=0;j<m_vertexArray.size();j++)
@@ -1348,13 +1348,13 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo
{
{
const float* vtx = poly->GetVertex(2)->getXYZ();
- btPoint3 vertex0(vtx[0],vtx[1],vtx[2]);
+ btVector3 vertex0(vtx[0],vtx[1],vtx[2]);
vtx = poly->GetVertex(1)->getXYZ();
- btPoint3 vertex1(vtx[0],vtx[1],vtx[2]);
+ btVector3 vertex1(vtx[0],vtx[1],vtx[2]);
vtx = poly->GetVertex(0)->getXYZ();
- btPoint3 vertex2(vtx[0],vtx[1],vtx[2]);
+ btVector3 vertex2(vtx[0],vtx[1],vtx[2]);
m_vertexArray.push_back(vertex0);
m_vertexArray.push_back(vertex1);
@@ -1365,13 +1365,13 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, bool polytope,bo
if (poly->VertexCount() == 4)
{
const float* vtx = poly->GetVertex(3)->getXYZ();
- btPoint3 vertex0(vtx[0],vtx[1],vtx[2]);
+ btVector3 vertex0(vtx[0],vtx[1],vtx[2]);
vtx = poly->GetVertex(2)->getXYZ();
- btPoint3 vertex1(vtx[0],vtx[1],vtx[2]);
+ btVector3 vertex1(vtx[0],vtx[1],vtx[2]);
vtx = poly->GetVertex(0)->getXYZ();
- btPoint3 vertex2(vtx[0],vtx[1],vtx[2]);
+ btVector3 vertex2(vtx[0],vtx[1],vtx[2]);
m_vertexArray.push_back(vertex0);
m_vertexArray.push_back(vertex1);
@@ -1442,7 +1442,7 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape()
break;
case PHY_SHAPE_POLYTOPE:
- collisionShape = new btConvexHullShape(&m_vertexArray.begin()->getX(), m_vertexArray.size());
+ collisionShape = new btConvexHullShape(&m_vertexArray[0].getX(), m_vertexArray.size());
break;
case PHY_SHAPE_MESH:
@@ -1457,12 +1457,14 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape()
{
collisionMeshData = new btTriangleMesh();
+ bool removeDuplicateVertices=true;
// m_vertexArray is necessarily a multiple of 3
- for (std::vector<btPoint3>::iterator it=m_vertexArray.begin(); it != m_vertexArray.end(); )
+ for (int i=0;i<m_vertexArray.size(); i+=3 )
{
- collisionMeshData->addTriangle(*it++,*it++,*it++);
+ collisionMeshData->addTriangle(m_vertexArray[i+2],m_vertexArray[i+1],m_vertexArray[i],removeDuplicateVertices);
}
+
btGImpactMeshShape* gimpactShape = new btGImpactMeshShape(collisionMeshData);
collisionShape = gimpactShape;
@@ -1475,10 +1477,11 @@ btCollisionShape* CcdShapeConstructionInfo::CreateBulletShape()
collisionMeshData = new btTriangleMesh(true,false);
collisionMeshData->m_weldingThreshold = m_weldingThreshold;
+ bool removeDuplicateVertices=true;
// m_vertexArray is necessarily a multiple of 3
- for (std::vector<btPoint3>::iterator it=m_vertexArray.begin(); it != m_vertexArray.end(); )
+ for (int i=0;i<m_vertexArray.size(); i+=3 )
{
- collisionMeshData->addTriangle(*it++,*it++,*it++);
+ collisionMeshData->addTriangle(m_vertexArray[i+2],m_vertexArray[i+1],m_vertexArray[i],removeDuplicateVertices);
}
// this shape will be shared and not deleted until shapeInfo is deleted
m_unscaledShape = new btBvhTriangleMeshShape( collisionMeshData, true );
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index c771aa2624b..deb3c0880e9 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -161,7 +161,7 @@ public:
btTransform m_childTrans;
btVector3 m_childScale;
void* m_userData;
- std::vector<btPoint3> m_vertexArray; // Contains both vertex array for polytope shape and
+ btAlignedObjectArray<btVector3> m_vertexArray; // Contains both vertex array for polytope shape and
// triangle array for concave mesh shape.
// In this case a triangle is made of 3 consecutive points
std::vector<int> m_polygonIndexArray; // Contains the array of polygon index in the
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index d2274c1e8d6..dd21e58bd68 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -317,8 +317,8 @@ static void DrawAabb(btIDebugDraw* debugDrawer,const btVector3& from,const btVec
CcdPhysicsEnvironment::CcdPhysicsEnvironment(btDispatcher* dispatcher,btOverlappingPairCache* pairCache)
-:m_scalingPropagated(false),
-m_numIterations(10),
+:m_numIterations(10),
+m_scalingPropagated(false),
m_numTimeSubSteps(1),
m_ccdMode(0),
m_solverType(-1),
@@ -326,8 +326,8 @@ m_profileTimings(0),
m_enableSatCollisionDetection(false),
m_solver(NULL),
m_ownPairCache(NULL),
-m_ownDispatcher(NULL),
-m_filterCallback(NULL)
+m_filterCallback(NULL),
+m_ownDispatcher(NULL)
{
for (int i=0;i<PHY_NUM_RESPONSE;i++)
@@ -337,6 +337,7 @@ m_filterCallback(NULL)
// m_collisionConfiguration = new btDefaultCollisionConfiguration();
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
+ //m_collisionConfiguration->setConvexConvexMultipointIterations();
if (!dispatcher)
{
@@ -356,6 +357,8 @@ m_filterCallback(NULL)
setSolverType(1);//issues with quickstep and memory allocations
// m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
m_dynamicsWorld = new btSoftRigidDynamicsWorld(dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
+ //m_dynamicsWorld->getSolverInfo().m_linearSlop = 0.01f;
+ //m_dynamicsWorld->getSolverInfo().m_solverMode= SOLVER_USE_WARMSTARTING + SOLVER_USE_2_FRICTION_DIRECTIONS + SOLVER_RANDMIZE_ORDER + SOLVER_USE_FRICTION_WARMSTARTING;
m_debugDrawer = 0;
m_gravity = btVector3(0.f,-10.f,0.f);
@@ -414,7 +417,7 @@ void CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
const btTransform& t = ctrl->GetCollisionObject()->getWorldTransform();
- btPoint3 minAabb,maxAabb;
+ btVector3 minAabb,maxAabb;
shapeinterface->getAabb(t,minAabb,maxAabb);
@@ -560,6 +563,11 @@ void CcdPhysicsEnvironment::beginFrame()
}
+void CcdPhysicsEnvironment::debugDrawWorld()
+{
+ if (m_dynamicsWorld->getDebugDrawer() && m_dynamicsWorld->getDebugDrawer()->getDebugMode() >0)
+ m_dynamicsWorld->debugDrawWorld();
+}
bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
{
@@ -596,9 +604,6 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
veh->SyncWheels();
}
- if (m_dynamicsWorld->getDebugDrawer() && m_dynamicsWorld->getDebugDrawer()->getDebugMode() >0)
- m_dynamicsWorld->debugDrawWorld();
-
CallbackTriggers();
@@ -845,7 +850,8 @@ void CcdPhysicsEnvironment::setSolverType(int solverType)
{
m_solver = new btSequentialImpulseConstraintSolver();
-// ((btSequentialImpulseConstraintSolver*)m_solver)->setSolverMode(btSequentialImpulseConstraintSolver::SOLVER_USE_WARMSTARTING | btSequentialImpulseConstraintSolver::SOLVER_RANDMIZE_ORDER);
+
+
break;
}
}
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
index 4b28d3fddfc..2f1f0bb254b 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
@@ -110,6 +110,8 @@ protected:
virtual void endFrame() {};
/// Perform an integration step of duration 'timeStep'.
virtual bool proceedDeltaTime(double curTime,float timeStep);
+
+ virtual void debugDrawWorld();
// virtual bool proceedDeltaTimeOneStep(float timeStep);
virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep){};
diff --git a/source/gameengine/Physics/Bullet/SConscript b/source/gameengine/Physics/Bullet/SConscript
index 51dbb4d86da..db9f3387bfe 100644
--- a/source/gameengine/Physics/Bullet/SConscript
+++ b/source/gameengine/Physics/Bullet/SConscript
@@ -7,9 +7,9 @@ incs = '. ../common #source/kernel/gen_system #intern/string #intern/moto/includ
incs += ' ' + env['BF_BULLET_INC']
-cflags = []
+cxxflags = []
if env['OURPLATFORM']=='win32-vc':
- cflags.append('/GR')
- cflags.append('/O2')
+ cxxflags.append ('/GR')
+ cxxflags.append ('/O2')
-env.BlenderLib ( 'bf_bullet', Split(sources), Split(incs), [], libtype=['core','player'], priority=[360,80] )
+env.BlenderLib ( 'bf_bullet', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350,80], cxx_compileflags=cxxflags )
diff --git a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h
index 2326bdee523..3d8eef2bae0 100644
--- a/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h
+++ b/source/gameengine/Physics/Sumo/Fuzzics/include/SM_Scene.h
@@ -46,7 +46,7 @@
#include "SM_Object.h"
-typedef enum
+enum
{
FH_RESPONSE,
SENSOR_RESPONSE, /* Touch Sensors */
diff --git a/source/gameengine/Physics/common/PHY_DynamicTypes.h b/source/gameengine/Physics/common/PHY_DynamicTypes.h
index 09126264dcc..c5cf92b553a 100644
--- a/source/gameengine/Physics/common/PHY_DynamicTypes.h
+++ b/source/gameengine/Physics/common/PHY_DynamicTypes.h
@@ -36,7 +36,7 @@ struct PHY__Vector3
};
//typedef float PHY__Vector3[4];
-typedef enum
+enum
{
PHY_FH_RESPONSE,
PHY_SENSOR_RESPONSE, /* Touch Sensors */
diff --git a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
index 0e9c571924c..226ba3a7e74 100644
--- a/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
+++ b/source/gameengine/Physics/common/PHY_IPhysicsEnvironment.h
@@ -90,6 +90,8 @@ class PHY_IPhysicsEnvironment
virtual void endFrame() = 0;
/// Perform an integration step of duration 'timeStep'.
virtual bool proceedDeltaTime(double curTime,float timeStep)=0;
+ ///draw debug lines (make sure to call this during the render phase, otherwise lines are not drawn properly)
+ virtual void debugDrawWorld(){}
virtual void setFixedTimeStep(bool useFixedTimeStep,float fixedTimeStep)=0;
//returns 0.f if no fixed timestep is used
virtual float getFixedTimeStep()=0;
diff --git a/source/gameengine/Physics/common/SConscript b/source/gameengine/Physics/common/SConscript
index aead31fb73e..4d7c808f49b 100644
--- a/source/gameengine/Physics/common/SConscript
+++ b/source/gameengine/Physics/common/SConscript
@@ -5,4 +5,9 @@ sources = 'PHY_IMotionState.cpp PHY_IPhysicsController.cpp PHY_IPhysicsEnvironme
incs = '. ../Dummy #intern/moto/include'
-env.BlenderLib ( 'bf_common', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350, 90] )
+cxxflags = []
+if env['OURPLATFORM']=='win32-vc':
+ cxxflags.append ('/GR')
+ cxxflags.append ('/O2')
+
+env.BlenderLib ( 'bf_common', Split(sources), Split(incs), [], libtype=['core','player'], priority=[360, 90], cxx_compileflags = cxxflags )
diff --git a/source/gameengine/PyDoc/GameLogic.py b/source/gameengine/PyDoc/GameLogic.py
index 9dab7db6081..0524a9df355 100644
--- a/source/gameengine/PyDoc/GameLogic.py
+++ b/source/gameengine/PyDoc/GameLogic.py
@@ -140,6 +140,14 @@ Documentation for the GameLogic Module.
@var KX_SOUNDACT_LOOPEND: See L{KX_SoundActuator}
@var KX_SOUNDACT_LOOPBIDIRECTIONAL: See L{KX_SoundActuator}
@var KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP: See L{KX_SoundActuator}
+
+@group Radar Sensor: KX_RADAR_AXIS_POS_X, KX_RADAR_AXIS_POS_Y, KX_RADAR_AXIS_POS_Z, KX_RADAR_AXIS_NEG_X, KX_RADAR_AXIS_NEG_Y, KX_RADAR_AXIS_NEG_Z
+@var KX_RADAR_AXIS_POS_X: See L{KX_RadarSensor}
+@var KX_RADAR_AXIS_POS_Y: See L{KX_RadarSensor}
+@var KX_RADAR_AXIS_POS_Z: See L{KX_RadarSensor}
+@var KX_RADAR_AXIS_NEG_X: See L{KX_RadarSensor}
+@var KX_RADAR_AXIS_NEG_Y: See L{KX_RadarSensor}
+@var KX_RADAR_AXIS_NEG_Z: See L{KX_RadarSensor}
"""
@@ -159,7 +167,7 @@ def addActiveActuator(actuator, activate):
"""
Activates the given actuator.
- @type actuator: L{SCA_IActuator}
+ @type actuator: L{SCA_IActuator} or the actuator name as a string.
@type activate: boolean
@param activate: whether to activate or deactivate the given actuator.
"""
diff --git a/source/gameengine/PyDoc/KX_CameraActuator.py b/source/gameengine/PyDoc/KX_CameraActuator.py
index 9a9abaf3d57..6ffc55a5854 100644
--- a/source/gameengine/PyDoc/KX_CameraActuator.py
+++ b/source/gameengine/PyDoc/KX_CameraActuator.py
@@ -6,6 +6,16 @@ class KX_CameraActuator(SCA_IActuator):
"""
Applies changes to a camera.
+ @ivar min: minimum distance to the target object maintained by the actuator
+ @type min: float
+ @ivar max: maximum distance to stay from the target object
+ @type max: float
+ @ivar height: height to stay above the target object
+ @type height: float
+ @ivar xy: axis this actuator is tracking, true=X, false=Y
+ @type xy: boolean
+ @ivar object: the object this actuator tracks.
+ @type object: KX_GameObject or None
@author: snail
"""
def getObject(name_only = 1):
diff --git a/source/gameengine/PyDoc/KX_GameObject.py b/source/gameengine/PyDoc/KX_GameObject.py
index efeffab2eed..4f389a1ae4f 100644
--- a/source/gameengine/PyDoc/KX_GameObject.py
+++ b/source/gameengine/PyDoc/KX_GameObject.py
@@ -7,7 +7,7 @@ class KX_GameObject:
Properties assigned to game objects are accessible as attributes of this class.
- @ivar name: The object's name.
+ @ivar name: The object's name. (Read only)
@type name: string.
@ivar mass: The object's mass (provided the object has a physics controller). Read only.
@type mass: float
diff --git a/source/gameengine/PyDoc/KX_NearSensor.py b/source/gameengine/PyDoc/KX_NearSensor.py
index fef2e4b2acc..a8c408827fe 100644
--- a/source/gameengine/PyDoc/KX_NearSensor.py
+++ b/source/gameengine/PyDoc/KX_NearSensor.py
@@ -5,5 +5,10 @@ from KX_TouchSensor import *
class KX_NearSensor(KX_TouchSensor):
"""
A near sensor is a specialised form of touch sensor.
+
+ @ivar distance: The near sensor activates when an object is within this distance.
+ @type distance: float
+ @ivar resetDistance: The near sensor deactivates when the object exceeds this distance.
+ @type resetDistance: float
"""
diff --git a/source/gameengine/PyDoc/KX_ParentActuator.py b/source/gameengine/PyDoc/KX_ParentActuator.py
index 6d6e0937257..7b5625ec82d 100644
--- a/source/gameengine/PyDoc/KX_ParentActuator.py
+++ b/source/gameengine/PyDoc/KX_ParentActuator.py
@@ -5,6 +5,9 @@ from SCA_IActuator import *
class KX_ParentActuator(SCA_IActuator):
"""
The parent actuator can set or remove an objects parent object.
+
+ @ivar object: the object this actuator sets the parent too.
+ @type object: KX_GameObject or None
"""
def setObject(object):
"""
diff --git a/source/gameengine/PyDoc/KX_RadarSensor.py b/source/gameengine/PyDoc/KX_RadarSensor.py
index 64be858371a..b68bf4ea0f3 100644
--- a/source/gameengine/PyDoc/KX_RadarSensor.py
+++ b/source/gameengine/PyDoc/KX_RadarSensor.py
@@ -5,8 +5,26 @@ from KX_NearSensor import *
class KX_RadarSensor(KX_NearSensor):
"""
Radar sensor is a near sensor with a conical sensor object.
+
+ @ivar coneOrigin: The origin of the cone with which to test. The origin
+ is in the middle of the cone.
+ (Read only)
+ @type coneOrigin: list of floats [x, y, z]
+ @ivar coneTarget: The center of the bottom face of the cone with which to test.
+ (Read only)
+ @type coneTarget: list of floats [x, y, z]
+ @ivar distance: The height of the cone with which to test.
+ @type distance: float
+ @ivar angle: The angle of the cone (in degrees) with which to test.
+ @type angle: float from 0 to 360
+ @ivar axis: The axis on which the radar cone is cast
+ @type axis: int from 0 to 5
+ KX_RADAR_AXIS_POS_X, KX_RADAR_AXIS_POS_Y, KX_RADAR_AXIS_POS_Z,
+ KX_RADAR_AXIS_NEG_X, KX_RADAR_AXIS_NEG_Y, KX_RADAR_AXIS_NEG_Z
"""
+
+ #--The following methods are deprecated, please use properties instead.
def getConeOrigin():
"""
Returns the origin of the cone with which to test. The origin
diff --git a/source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py b/source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py
index c3b2e947ddb..56068fa641a 100644
--- a/source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py
+++ b/source/gameengine/PyDoc/KX_SCA_AddObjectActuator.py
@@ -5,6 +5,10 @@ from SCA_IActuator import *
class KX_SCA_AddObjectActuator(SCA_IActuator):
"""
Edit Object Actuator (in Add Object Mode)
+ @ivar object: the object this actuator adds.
+ @type object: KX_GameObject or None
+ @ivar objectLastCreated: the last added object from this actuator (read only).
+ @type objectLastCreated: KX_GameObject or None
@warning: An Add Object actuator will be ignored if at game start, the linked object doesn't exist
(or is empty) or the linked object is in an active layer.
diff --git a/source/gameengine/PyDoc/KX_Scene.py b/source/gameengine/PyDoc/KX_Scene.py
index 4a0a7a9556d..5e357e6eefc 100644
--- a/source/gameengine/PyDoc/KX_Scene.py
+++ b/source/gameengine/PyDoc/KX_Scene.py
@@ -39,6 +39,8 @@ class KX_Scene:
@ivar name: The scene's name
@type name: string
+ @type objects: A list of objects in the scene.
+ @type objects: list [L{KX_GameObject}]
@ivar active_camera: The current active camera
@type active_camera: L{KX_Camera}
@ivar suspended: True if the scene is suspended.
@@ -68,3 +70,16 @@ class KX_Scene:
@rtype: string
"""
+ def addObject(object, other, time=0)
+ """
+ Adds an object to the scene like the Add Object Actuator would, and returns the created object.
+
+ @param object: The object to add
+ @type object: L{KX_GameObject} or string
+ @param other: The object's center to use when adding the object
+ @type other: L{KX_GameObject} or string
+ @param time: The lifetime of the added object, in frames. A time of 0 means the object will last forever.
+ @type time: int
+
+ @rtype: L{KX_GameObject}
+ """
diff --git a/source/gameengine/PyDoc/KX_TouchSensor.py b/source/gameengine/PyDoc/KX_TouchSensor.py
index f2cc101af10..d7277be4c2a 100644
--- a/source/gameengine/PyDoc/KX_TouchSensor.py
+++ b/source/gameengine/PyDoc/KX_TouchSensor.py
@@ -1,36 +1,55 @@
# $Id$
# Documentation for KX_TouchSensor
from SCA_ISensor import *
+from KX_GameObject import *
class KX_TouchSensor(SCA_ISensor):
"""
Touch sensor detects collisions between objects.
+
+ @ivar property: The property or material to collide with.
+ @type property: string
+ @ivar useMaterial: Determines if the sensor is looking for a property or material.
+ KX_True = Find material; KX_False = Find property
+ @type useMaterial: boolean
+ @ivar pulseCollisions: The last collided object.
+ @type pulseCollisions: bool
+ @ivar objectHit: The last collided object. (Read Only)
+ @type objectHit: L{KX_GameObject} or None
+ @ivar objectHitList: A list of colliding objects. (Read Only)
+ @type objectHitList: list
"""
+
+ #--The following methods are deprecated, please use properties instead.
def setProperty(name):
"""
+ DEPRECATED: use the property property
Set the property or material to collide with. Use
setTouchMaterial() to switch between properties and
materials.
@type name: string
"""
+
def getProperty():
"""
+ DEPRECATED: use the property property
Returns the property or material to collide with. Use
getTouchMaterial() to find out whether this sensor
- looks for properties or materials.
+ looks for properties or materials. (B{deprecated})
@rtype: string
"""
-
def getHitObject():
"""
- Returns the last object hit by this touch sensor.
+ DEPRECATED: use the objectHit property
+ Returns the last object hit by this touch sensor. (B{deprecated})
@rtype: L{KX_GameObject}
"""
def getHitObjectList():
"""
- Returns a list of all objects hit in the last frame.
+ DEPRECATED: use the objectHitList property
+ Returns a list of all objects hit in the last frame. (B{deprecated})
Only objects that have the requisite material/property are listed.
@@ -38,13 +57,7 @@ class KX_TouchSensor(SCA_ISensor):
"""
def getTouchMaterial():
"""
+ DEPRECATED: use the useMaterial property
Returns KX_TRUE if this sensor looks for a specific material,
- KX_FALSE if it looks for a specific property.
- """
- def setTouchMaterial(flag):
- """
- Set flag to KX_TRUE to switch on positive pulse mode,
- KX_FALSE to switch off positive pulse mode.
-
- @type flag: KX_TRUE or KX_FALSE.
+ KX_FALSE if it looks for a specific property. (B{deprecated})
"""
diff --git a/source/gameengine/PyDoc/KX_TrackToActuator.py b/source/gameengine/PyDoc/KX_TrackToActuator.py
index 948302991b7..730ab21166b 100644
--- a/source/gameengine/PyDoc/KX_TrackToActuator.py
+++ b/source/gameengine/PyDoc/KX_TrackToActuator.py
@@ -13,6 +13,8 @@ class KX_TrackToActuator(SCA_IActuator):
C{ERROR: GameObject I{OBName} no object in EditObjectActuator I{ActuatorName}}
+ @ivar object: the object this actuator tracks.
+ @type object: KX_GameObject or None
"""
def setObject(object):
"""
diff --git a/source/gameengine/PyDoc/SCA_DelaySensor.py b/source/gameengine/PyDoc/SCA_DelaySensor.py
index b99ed08bed5..6560df6573e 100644
--- a/source/gameengine/PyDoc/SCA_DelaySensor.py
+++ b/source/gameengine/PyDoc/SCA_DelaySensor.py
@@ -20,10 +20,9 @@ class SCA_DelaySensor(SCA_ISensor):
@type delay: integer.
@ivar duration: length of the ON period in number of frame after the initial OFF period.
If duration is greater than 0, a negative trigger is sent at the end of the ON pulse.
- @type duration: integer
- @ivar repeat: 1 if the OFF-ON cycle should be repeated indefinately, 0 if it should run once.
- @type repeat: integer
-
+ @type duration: integer
+ @ivar repeat: 1 if the OFF-ON cycle should be repeated indefinately, 0 if it should run once.
+ @type repeat: integer
"""
def setDelay(delay):
"""
diff --git a/source/gameengine/PyDoc/SCA_PythonController.py b/source/gameengine/PyDoc/SCA_PythonController.py
index 06f2b7e9d1d..9684b41d481 100644
--- a/source/gameengine/PyDoc/SCA_PythonController.py
+++ b/source/gameengine/PyDoc/SCA_PythonController.py
@@ -15,7 +15,17 @@ class SCA_PythonController(SCA_IController):
This can be used with the GameObject's state to test if the controller is active.
@type state: integer
"""
-
+ def activate(actuator):
+ """
+ Activates an actuator attached to this controller.
+ @type actuator: actuator or the actuator name as a string
+ """
+ def deactivate(actuator):
+ """
+ Deactivates an actuator attached to this controller.
+ @type actuator: actuator or the actuator name as a string
+ """
+
def getSensors():
"""
Gets a list of all sensors attached to this controller.
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
index fb3607f89f4..cd88112007b 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
@@ -143,7 +143,7 @@ const STR_String& RAS_IPolyMaterial::GetTextureName() const
return m_texturename;
}
-const unsigned int RAS_IPolyMaterial::GetFlag() const
+unsigned int RAS_IPolyMaterial::GetFlag() const
{
return m_flag;
}
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
index 218dd91cb30..e5b24070c4b 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
@@ -138,7 +138,7 @@ public:
const STR_String& GetMaterialName() const;
dword GetMaterialNameHash() const;
const STR_String& GetTextureName() const;
- const unsigned int GetFlag() const;
+ unsigned int GetFlag() const;
virtual bool UsesLighting(RAS_IRasterizer *rasty) const;
virtual bool UsesObjectColor() const;
diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h
index b4b90c3608b..83adcfd8321 100644
--- a/source/gameengine/Rasterizer/RAS_IRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h
@@ -255,6 +255,8 @@ public:
/**
*/
virtual const MT_Point3& GetCameraPosition()=0;
+ virtual bool GetCameraOrtho()=0;
+
/**
*/
virtual void SetFog(float start,
@@ -359,6 +361,8 @@ public:
virtual void SetPolygonOffset(float mult, float add) = 0;
virtual void DrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color)=0;
+ virtual void FlushDebugLines()=0;
+
virtual void SetTexCoordNum(int num) = 0;
diff --git a/source/gameengine/Rasterizer/RAS_IRenderTools.h b/source/gameengine/Rasterizer/RAS_IRenderTools.h
index 57f331e64cb..a289ffed492 100644
--- a/source/gameengine/Rasterizer/RAS_IRenderTools.h
+++ b/source/gameengine/Rasterizer/RAS_IRenderTools.h
@@ -134,6 +134,7 @@ public:
virtual
void
ProcessLighting(
+ RAS_IRasterizer *rasty,
int layer,
const MT_Transform& trans
)=0;
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
index ad8d7ebd5b0..d8631c1edf6 100644
--- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
@@ -517,9 +517,9 @@ bool RAS_MaterialBucket::ActivateMaterial(const MT_Transform& cameratrans, RAS_I
return false;
if (m_material->UsesLighting(rasty))
- rendertools->ProcessLighting(RAS_IRenderTools::RAS_LIGHT_OBJECT_LAYER, cameratrans);
+ rendertools->ProcessLighting(rasty, RAS_IRenderTools::RAS_LIGHT_OBJECT_LAYER, cameratrans);
else
- rendertools->ProcessLighting(-1, cameratrans);
+ rendertools->ProcessLighting(rasty, -1, cameratrans);
return true;
}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index 3cad5fe74f2..d4d1b73c772 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -59,6 +59,8 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
m_2DCanvas(canvas),
m_fogenabled(false),
m_time(0.0),
+ m_campos(0.0f, 0.0f, 0.0f),
+ m_camortho(false),
m_stereomode(RAS_STEREO_NOSTEREO),
m_curreye(RAS_STEREO_LEFTEYE),
m_eyeseparation(0.0),
@@ -325,13 +327,12 @@ void RAS_OpenGLRasterizer::ClearCachingInfo(void)
m_materialCachingInfo = 0;
}
-
-void RAS_OpenGLRasterizer::EndFrame()
+void RAS_OpenGLRasterizer::FlushDebugLines()
{
+//DrawDebugLines
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
- //DrawDebugLines
glBegin(GL_LINES);
for (unsigned int i=0;i<m_debugLines.size();i++)
{
@@ -346,8 +347,19 @@ void RAS_OpenGLRasterizer::EndFrame()
}
glEnd();
+ glEnable(GL_LIGHTING);
+ glEnable(GL_TEXTURE_2D);
+
m_debugLines.clear();
+}
+
+void RAS_OpenGLRasterizer::EndFrame()
+{
+
+
+ FlushDebugLines();
+
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
m_2DCanvas->EndFrame();
}
@@ -756,8 +768,9 @@ void RAS_OpenGLRasterizer::SetProjectionMatrix(MT_CmMatrix4x4 &mat)
glMatrixMode(GL_PROJECTION);
double* matrix = &mat(0,0);
glLoadMatrixd(matrix);
-}
+ m_camortho= (mat(3, 3) != 0.0f);
+}
void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
{
@@ -767,6 +780,8 @@ void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat)
mat.getValue(matrix);
/* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */
glLoadMatrixd(matrix);
+
+ m_camortho= (mat[3][3] != 0.0f);
}
MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
@@ -883,6 +898,10 @@ const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
return m_campos;
}
+bool RAS_OpenGLRasterizer::GetCameraOrtho()
+{
+ return m_camortho;
+}
void RAS_OpenGLRasterizer::SetCullFace(bool enable)
{
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
index d39fd642f86..83a9f759a8b 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
@@ -80,6 +80,7 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer
MT_Matrix4x4 m_viewmatrix;
MT_Matrix4x4 m_viewinvmatrix;
MT_Point3 m_campos;
+ bool m_camortho;
StereoMode m_stereomode;
StereoEye m_curreye;
@@ -168,6 +169,7 @@ public:
);
virtual const MT_Point3& GetCameraPosition();
+ virtual bool GetCameraOrtho();
virtual void SetFog(
float start,
@@ -238,6 +240,8 @@ public:
virtual void SetPolygonOffset(float mult, float add);
+ virtual void FlushDebugLines();
+
virtual void DrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,const MT_Vector3& color)
{
OglDebugLine line;
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript
index b9358ffde6b..c0b73e7644f 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript
@@ -6,4 +6,9 @@ sources = env.Glob('*.cpp')
incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/Rasterizer #source/gameengine/BlenderRoutines '
incs += ' #source/blender/gpu #extern/glew/include ' + env['BF_OPENGL_INC']
-env.BlenderLib ( 'bf_oglrasterizer', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350, 115] )
+cxxflags = []
+if env['OURPLATFORM']=='win32-vc':
+ cxxflags.append ('/GR')
+ cxxflags.append ('/O2')
+
+env.BlenderLib ( 'bf_oglrasterizer', Split(sources), Split(incs), [], libtype=['core','player'], priority=[350, 115], cxx_compileflags = cxxflags )
diff --git a/source/gameengine/Rasterizer/RAS_TexVert.cpp b/source/gameengine/Rasterizer/RAS_TexVert.cpp
index b92965ed1cc..210addfb927 100644
--- a/source/gameengine/Rasterizer/RAS_TexVert.cpp
+++ b/source/gameengine/Rasterizer/RAS_TexVert.cpp
@@ -59,10 +59,10 @@ const MT_Point3& RAS_TexVert::xyz()
void RAS_TexVert::SetRGBA(const MT_Vector4& rgba)
{
unsigned char *colp = (unsigned char*) &m_rgba;
- colp[0] = (unsigned char) (rgba[0]*255.0);
- colp[1] = (unsigned char) (rgba[1]*255.0);
- colp[2] = (unsigned char) (rgba[2]*255.0);
- colp[3] = (unsigned char) (rgba[3]*255.0);
+ colp[0] = (unsigned char) (rgba[0]*255.0f);
+ colp[1] = (unsigned char) (rgba[1]*255.0f);
+ colp[2] = (unsigned char) (rgba[2]*255.0f);
+ colp[3] = (unsigned char) (rgba[3]*255.0f);
}
@@ -71,7 +71,10 @@ void RAS_TexVert::SetXYZ(const MT_Point3& xyz)
xyz.getValue(m_localxyz);
}
-
+void RAS_TexVert::SetXYZ(const float *xyz)
+{
+ m_localxyz[0]= xyz[0]; m_localxyz[1]= xyz[1]; m_localxyz[2]= xyz[2];
+}
void RAS_TexVert::SetUV(const MT_Point2& uv)
{
@@ -111,15 +114,18 @@ void RAS_TexVert::SetTangent(const MT_Vector3& tangent)
}
// compare two vertices, and return TRUE if both are almost identical (they can be shared)
+#define _VEC_EQUAL3(_v1, _v2) (_v1[0]==_v2[0] && _v1[1]==_v2[1] && _v1[2]==_v2[2])
+#define _VEC_EQUAL2(_v1, _v2) (_v1[0]==_v2[0] && _v1[1]==_v2[1])
bool RAS_TexVert::closeTo(const RAS_TexVert* other)
{
return (m_flag == other->m_flag &&
m_rgba == other->m_rgba &&
- MT_fuzzyEqual(MT_Vector3(m_normal), MT_Vector3(other->m_normal)) &&
- MT_fuzzyEqual(MT_Vector3(m_tangent), MT_Vector3(other->m_tangent)) &&
- MT_fuzzyEqual(MT_Vector2(m_uv1), MT_Vector2(other->m_uv1)) &&
- MT_fuzzyEqual(MT_Vector2(m_uv2), MT_Vector2(other->m_uv2)) && // p --
- MT_fuzzyEqual(MT_Vector3(m_localxyz), MT_Vector3(other->m_localxyz))) ;
+ _VEC_EQUAL3(m_normal, other->m_normal) &&
+ _VEC_EQUAL3(m_tangent, other->m_tangent) &&
+ _VEC_EQUAL2(m_uv1, other->m_uv1) &&
+ _VEC_EQUAL2(m_uv2, other->m_uv2) // p --
+ /* we know the verts must be shared so dont need to check this */
+ /*&& FAST_MT_fuzzyEqual3(m_localxyz, other->m_localxyz)*/) ;
}
short RAS_TexVert::getFlag() const
diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h
index 54da109cbf1..811867f3579 100644
--- a/source/gameengine/Rasterizer/RAS_TexVert.h
+++ b/source/gameengine/Rasterizer/RAS_TexVert.h
@@ -110,11 +110,12 @@ public:
return (unsigned char *) &m_rgba;
}
- const unsigned int getOrigIndex() const {
+ unsigned int getOrigIndex() const {
return m_origindex;
}
void SetXYZ(const MT_Point3& xyz);
+ void SetXYZ(const float *xyz);
void SetUV(const MT_Point2& uv);
void SetUV2(const MT_Point2& uv);
diff --git a/source/gameengine/Rasterizer/SConscript b/source/gameengine/Rasterizer/SConscript
index ebb2f28ec16..9f4cd61e7bb 100644
--- a/source/gameengine/Rasterizer/SConscript
+++ b/source/gameengine/Rasterizer/SConscript
@@ -7,9 +7,9 @@ sources = env.Glob('*.cpp')
incs = '. #source/kernel/gen_system #intern/string #intern/moto/include #source/gameengine/BlenderRoutines #extern/glew/include #source/gameengine/Expressions #source/blender/blenkernel #source/blender/makesdna'
incs += ' ' + env['BF_PYTHON_INC']
+cxxflags = []
if env['OURPLATFORM']=='win32-vc':
- cflags = []
- cflags.append('/Ox')
- env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), [], libtype=['core','player'], priority=[350,115], compileflags = cflags )
-else:
- env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), [], libtype=['core','player'], priority=[350,115] )
+ cxxflags.append ('/GR')
+ cxxflags.append ('/O2')
+
+env.BlenderLib ( 'bf_rasterizer', sources, Split(incs), [], libtype=['core','player'], priority=[350,115], cxx_compileflags = cxxflags )
diff --git a/source/gameengine/SConscript b/source/gameengine/SConscript
index 39824cac1aa..864e4c3ebee 100644
--- a/source/gameengine/SConscript
+++ b/source/gameengine/SConscript
@@ -15,10 +15,12 @@ SConscript(['BlenderRoutines/SConscript',
'Rasterizer/RAS_OpenGLRasterizer/SConscript',
'SceneGraph/SConscript',
'Physics/Bullet/SConscript',
- 'Physics/Sumo/SConscript',
'VideoTexture/SConscript'
])
+if env['WITH_BF_SOLID']:
+ SConscript(['Physics/Sumo/SConscript'])
+
if env['WITH_BF_PLAYER']:
SConscript(['GamePlayer/SConscript'])
diff --git a/source/gameengine/SceneGraph/SConscript b/source/gameengine/SceneGraph/SConscript
index a0733b6c51c..0692b170a61 100644
--- a/source/gameengine/SceneGraph/SConscript
+++ b/source/gameengine/SceneGraph/SConscript
@@ -6,4 +6,9 @@ sources = env.Glob('*.cpp')
incs = '. #intern/moto/include'
-env.BlenderLib ( 'bf_scenegraph', sources, Split(incs), [], libtype=['core','player'], priority=[280,125] )
+cxxflags = []
+if env['OURPLATFORM']=='win32-vc':
+ cxxflags.append ('/GR')
+ cxxflags.append ('/O2')
+
+env.BlenderLib ( 'bf_scenegraph', sources, Split(incs), [], libtype=['core','player'], priority=[325,125], cxx_compileflags = cxxflags )
diff --git a/source/gameengine/SceneGraph/SG_BBox.cpp b/source/gameengine/SceneGraph/SG_BBox.cpp
index 4bd2805978e..a44262d04f7 100644
--- a/source/gameengine/SceneGraph/SG_BBox.cpp
+++ b/source/gameengine/SceneGraph/SG_BBox.cpp
@@ -34,8 +34,8 @@
#include "SG_Node.h"
SG_BBox::SG_BBox() :
- m_min(MT_Point3(0., 0., 0.)),
- m_max(MT_Point3(0., 0., 0.))
+ m_min(0., 0., 0.),
+ m_max(0., 0., 0.)
{
}
diff --git a/source/gameengine/SceneGraph/SG_Spatial.cpp b/source/gameengine/SceneGraph/SG_Spatial.cpp
index 5ba116e59db..99aeb3e72ee 100644
--- a/source/gameengine/SceneGraph/SG_Spatial.cpp
+++ b/source/gameengine/SceneGraph/SG_Spatial.cpp
@@ -44,13 +44,13 @@ SG_Spatial(
):
SG_IObject(clientobj,clientinfo,callbacks),
- m_localPosition(MT_Point3(0.0,0.0,0.0)),
- m_localRotation(MT_Matrix3x3(1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0)),
- m_localScaling(MT_Vector3(1.f,1.f,1.f)),
+ m_localPosition(0.0,0.0,0.0),
+ m_localRotation(1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0),
+ m_localScaling(1.f,1.f,1.f),
- m_worldPosition(MT_Point3(0.0,0.0,0.0)),
- m_worldRotation(MT_Matrix3x3(1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0)),
- m_worldScaling(MT_Vector3(1.f,1.f,1.f)),
+ m_worldPosition(0.0,0.0,0.0),
+ m_worldRotation(1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0),
+ m_worldScaling(1.f,1.f,1.f),
m_parent_relation (NULL),
@@ -297,6 +297,13 @@ GetWorldScaling(
return m_worldScaling;
}
+void SG_Spatial::SetWorldFromLocalTransform()
+{
+ m_worldPosition= m_localPosition;
+ m_worldScaling= m_localScaling;
+ m_worldRotation= m_localRotation;
+}
+
SG_BBox& SG_Spatial::BBox()
{
return m_bbox;
diff --git a/source/gameengine/SceneGraph/SG_Spatial.h b/source/gameengine/SceneGraph/SG_Spatial.h
index 28848b0f933..6ccec2aa9c1 100644
--- a/source/gameengine/SceneGraph/SG_Spatial.h
+++ b/source/gameengine/SceneGraph/SG_Spatial.h
@@ -176,6 +176,8 @@ public:
GetWorldScaling(
) const ;
+ void SetWorldFromLocalTransform();
+
MT_Transform GetWorldTransform() const;
bool ComputeWorldTransforms( const SG_Spatial *parent);
diff --git a/source/gameengine/VideoTexture/CMakeLists.txt b/source/gameengine/VideoTexture/CMakeLists.txt
index 12b6b83cabe..9d1bb89d2ca 100644
--- a/source/gameengine/VideoTexture/CMakeLists.txt
+++ b/source/gameengine/VideoTexture/CMakeLists.txt
@@ -53,7 +53,7 @@ SET(INC
)
IF(WITH_FFMPEG)
- SET(INC ${INC} ${FFMPEG_INC})
+ SET(INC ${INC} ${FFMPEG_INC} ${PTHREADS_INC})
ADD_DEFINITIONS(-DWITH_FFMPEG)
ADD_DEFINITIONS(-D__STDC_CONSTANT_MACROS)
ENDIF(WITH_FFMPEG)
diff --git a/source/gameengine/VideoTexture/FilterBase.cpp b/source/gameengine/VideoTexture/FilterBase.cpp
index b0112cd355b..b2abd4354fd 100644
--- a/source/gameengine/VideoTexture/FilterBase.cpp
+++ b/source/gameengine/VideoTexture/FilterBase.cpp
@@ -69,7 +69,7 @@ FilterBase * FilterBase::findFirst (void)
{
// find first filter in chain
FilterBase * frst;
- for (frst = this; frst->m_previous != NULL; frst = frst->m_previous->m_filter);
+ for (frst = this; frst->m_previous != NULL; frst = frst->m_previous->m_filter) {};
// set first filter
return frst;
}
diff --git a/source/gameengine/VideoTexture/FilterSource.h b/source/gameengine/VideoTexture/FilterSource.h
index 7e90747d252..6385ed5108f 100644
--- a/source/gameengine/VideoTexture/FilterSource.h
+++ b/source/gameengine/VideoTexture/FilterSource.h
@@ -189,9 +189,10 @@ protected:
int d = m_buffU[offset] - 128;
int e = m_buffV[offset] - 128;
// if horizontal interpolation is needed
- if ((x & 1) == 1)
+ if ((x & 1) == 1) {
// if vertical interpolation is needed too
if ((y & 1) == 1)
+ {
// if this pixel is on the edge
if (isEdge(x, y, size))
{
@@ -206,7 +207,8 @@ protected:
e = interpolVH(m_buffV + offset) - 128;
}
// otherwise use horizontal interpolation only
- else
+ }
+ else {
// if this pixel is on the edge
if (isEdge(x, y, size))
{
@@ -221,6 +223,8 @@ protected:
e = interpolH(m_buffV + offset) - 128;
}
// otherwise if only vertical interpolation is needed
+ }
+ }
else if ((y & 1) == 1)
// if this pixel is on the edge
if (isEdge(x, y, size))
diff --git a/source/gameengine/VideoTexture/Makefile b/source/gameengine/VideoTexture/Makefile
index e4a70428c60..8677ed5c177 100644
--- a/source/gameengine/VideoTexture/Makefile
+++ b/source/gameengine/VideoTexture/Makefile
@@ -60,6 +60,9 @@ CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
ifeq ($(WITH_FFMPEG),true)
CPPFLAGS += -DWITH_FFMPEG
CPPFLAGS += $(NAN_FFMPEGCFLAGS)
+ ifdef NAN_PTHREADS
+ CPPFLAGS += -I$(NAN_PTHREADS)/include
+ endif
endif
diff --git a/source/gameengine/VideoTexture/SConscript b/source/gameengine/VideoTexture/SConscript
index 36bb1ea6257..920da8ffb2e 100644
--- a/source/gameengine/VideoTexture/SConscript
+++ b/source/gameengine/VideoTexture/SConscript
@@ -15,18 +15,19 @@ incs += ' #source/blender/gpu #source/kernel/gen_system #intern/string #intern/m
incs += ' #intern/guardedalloc #intern/SoundSystem'
incs += ' #extern/glew/include'
-cflags = []
defs = ''
-if env['OURPLATFORM'] == 'win32-vc':
- cflags.append('/GR')
- cflags.append('/Ox')
+cxxflags = []
+if env['OURPLATFORM']=='win32-vc':
+ cxxflags.append ('/GR')
+ cxxflags.append ('/O2')
+
incs += ' ' + env['BF_PYTHON_INC']
#incs += ' ' + env['BF_OPENGL_INC']
if env['WITH_BF_FFMPEG']:
defs += ' WITH_FFMPEG'
- incs += ' ' + env['BF_FFMPEG_INC']
+ incs += ' ' + env['BF_FFMPEG_INC'] + ' ' + env['BF_PTHREADS_INC']
defs += ' __STDC_CONSTANT_MACROS'
-env.BlenderLib ( 'bf_videotex', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[300, 72], compileflags = cflags )
+env.BlenderLib ( 'bf_videotex', sources, Split(incs), Split(defs), libtype=['core','player'], priority=[300, 72], cxx_compileflags = cxxflags )
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.cpp b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
index 02798c7e596..5265b0ecb93 100644
--- a/source/gameengine/VideoTexture/VideoFFmpeg.cpp
+++ b/source/gameengine/VideoTexture/VideoFFmpeg.cpp
@@ -55,7 +55,8 @@ m_codec(NULL), m_formatCtx(NULL), m_codecCtx(NULL),
m_frame(NULL), m_frameDeinterlaced(NULL), m_frameRGB(NULL), m_imgConvertCtx(NULL),
m_deinterlace(false), m_preseek(0), m_videoStream(-1), m_baseFrameRate(25.0),
m_lastFrame(-1), m_eof(false), m_curPosition(-1), m_startTime(0),
-m_captWidth(0), m_captHeight(0), m_captRate(0.f), m_isImage(false)
+m_captWidth(0), m_captHeight(0), m_captRate(0.f), m_isImage(false),
+m_isThreaded(false), m_stopThread(false), m_cacheStarted(false)
{
// set video format
m_format = RGB24;
@@ -63,6 +64,12 @@ m_captWidth(0), m_captHeight(0), m_captRate(0.f), m_isImage(false)
setFlip(true);
// construction is OK
*hRslt = S_OK;
+ m_thread.first = m_thread.last = NULL;
+ pthread_mutex_init(&m_cacheMutex, NULL);
+ m_frameCacheFree.first = m_frameCacheFree.last = NULL;
+ m_frameCacheBase.first = m_frameCacheBase.last = NULL;
+ m_packetCacheFree.first = m_packetCacheFree.last = NULL;
+ m_packetCacheBase.first = m_packetCacheBase.last = NULL;
}
// destructor
@@ -75,6 +82,7 @@ VideoFFmpeg::~VideoFFmpeg ()
bool VideoFFmpeg::release()
{
// release
+ stopCache();
if (m_codecCtx)
{
avcodec_close(m_codecCtx);
@@ -112,6 +120,29 @@ bool VideoFFmpeg::release()
return true;
}
+AVFrame *VideoFFmpeg::allocFrameRGB()
+{
+ AVFrame *frame;
+ frame = avcodec_alloc_frame();
+ if (m_format == RGBA32)
+ {
+ avpicture_fill((AVPicture*)frame,
+ (uint8_t*)MEM_callocN(avpicture_get_size(
+ PIX_FMT_RGBA,
+ m_codecCtx->width, m_codecCtx->height),
+ "ffmpeg rgba"),
+ PIX_FMT_RGBA, m_codecCtx->width, m_codecCtx->height);
+ } else
+ {
+ avpicture_fill((AVPicture*)frame,
+ (uint8_t*)MEM_callocN(avpicture_get_size(
+ PIX_FMT_RGB24,
+ m_codecCtx->width, m_codecCtx->height),
+ "ffmpeg rgb"),
+ PIX_FMT_RGB24, m_codecCtx->width, m_codecCtx->height);
+ }
+ return frame;
+}
// set initial parameters
void VideoFFmpeg::initParams (short width, short height, float rate, bool image)
@@ -122,6 +153,7 @@ void VideoFFmpeg::initParams (short width, short height, float rate, bool image)
m_isImage = image;
}
+
int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AVFormatParameters *formatParams)
{
AVFormatContext *formatCtx;
@@ -189,7 +221,6 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV
m_videoStream = videoStream;
m_frame = avcodec_alloc_frame();
m_frameDeinterlaced = avcodec_alloc_frame();
- m_frameRGB = avcodec_alloc_frame();
// allocate buffer if deinterlacing is required
avpicture_fill((AVPicture*)m_frameDeinterlaced,
@@ -207,12 +238,6 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV
{
// allocate buffer to store final decoded frame
m_format = RGBA32;
- avpicture_fill((AVPicture*)m_frameRGB,
- (uint8_t*)MEM_callocN(avpicture_get_size(
- PIX_FMT_RGBA,
- m_codecCtx->width, m_codecCtx->height),
- "ffmpeg rgba"),
- PIX_FMT_RGBA, m_codecCtx->width, m_codecCtx->height);
// allocate sws context
m_imgConvertCtx = sws_getContext(
m_codecCtx->width,
@@ -227,12 +252,6 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV
{
// allocate buffer to store final decoded frame
m_format = RGB24;
- avpicture_fill((AVPicture*)m_frameRGB,
- (uint8_t*)MEM_callocN(avpicture_get_size(
- PIX_FMT_RGB24,
- m_codecCtx->width, m_codecCtx->height),
- "ffmpeg rgb"),
- PIX_FMT_RGB24, m_codecCtx->width, m_codecCtx->height);
// allocate sws context
m_imgConvertCtx = sws_getContext(
m_codecCtx->width,
@@ -244,19 +263,247 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV
SWS_FAST_BILINEAR,
NULL, NULL, NULL);
}
+ m_frameRGB = allocFrameRGB();
+
if (!m_imgConvertCtx) {
avcodec_close(m_codecCtx);
+ m_codecCtx = NULL;
av_close_input_file(m_formatCtx);
+ m_formatCtx = NULL;
av_free(m_frame);
+ m_frame = NULL;
MEM_freeN(m_frameDeinterlaced->data[0]);
av_free(m_frameDeinterlaced);
+ m_frameDeinterlaced = NULL;
MEM_freeN(m_frameRGB->data[0]);
av_free(m_frameRGB);
+ m_frameRGB = NULL;
return -1;
}
return 0;
}
+/*
+ * This thread is used to load video frame asynchronously.
+ * It provides a frame caching service.
+ * The main thread is responsible for positionning the frame pointer in the
+ * file correctly before calling startCache() which starts this thread.
+ * The cache is organized in two layers: 1) a cache of 20-30 undecoded packets to keep
+ * memory and CPU low 2) a cache of 5 decoded frames.
+ * If the main thread does not find the frame in the cache (because the video has restarted
+ * or because the GE is lagging), it stops the cache with StopCache() (this is a synchronous
+ * function: it sends a signal to stop the cache thread and wait for confirmation), then
+ * change the position in the stream and restarts the cache thread.
+ */
+void *VideoFFmpeg::cacheThread(void *data)
+{
+ VideoFFmpeg* video = (VideoFFmpeg*)data;
+ // holds the frame that is being decoded
+ CacheFrame *currentFrame = NULL;
+ CachePacket *cachePacket;
+ bool endOfFile = false;
+ int frameFinished = 0;
+
+ while (!video->m_stopThread)
+ {
+ // packet cache is used solely by this thread, no need to lock
+ // In case the stream/file contains other stream than the one we are looking for,
+ // allow a bit of cycling to get rid quickly of those frames
+ frameFinished = 0;
+ while ( !endOfFile
+ && (cachePacket = (CachePacket *)video->m_packetCacheFree.first) != NULL
+ && frameFinished < 25)
+ {
+ // free packet => packet cache is not full yet, just read more
+ if (av_read_frame(video->m_formatCtx, &cachePacket->packet)>=0)
+ {
+ if (cachePacket->packet.stream_index == video->m_videoStream)
+ {
+ // make sure fresh memory is allocated for the packet and move it to queue
+ av_dup_packet(&cachePacket->packet);
+ BLI_remlink(&video->m_packetCacheFree, cachePacket);
+ BLI_addtail(&video->m_packetCacheBase, cachePacket);
+ break;
+ } else {
+ // this is not a good packet for us, just leave it on free queue
+ // Note: here we could handle sound packet
+ av_free_packet(&cachePacket->packet);
+ frameFinished++;
+ }
+
+ } else {
+ if (video->m_isFile)
+ // this mark the end of the file
+ endOfFile = true;
+ // if we cannot read a packet, no need to continue
+ break;
+ }
+ }
+ // frame cache is also used by main thread, lock
+ if (currentFrame == NULL)
+ {
+ // no current frame being decoded, take free one
+ pthread_mutex_lock(&video->m_cacheMutex);
+ if ((currentFrame = (CacheFrame *)video->m_frameCacheFree.first) != NULL)
+ BLI_remlink(&video->m_frameCacheFree, currentFrame);
+ pthread_mutex_unlock(&video->m_cacheMutex);
+ }
+ if (currentFrame != NULL)
+ {
+ // this frame is out of free and busy queue, we can manipulate it without locking
+ frameFinished = 0;
+ while (!frameFinished && (cachePacket = (CachePacket *)video->m_packetCacheBase.first) != NULL)
+ {
+ BLI_remlink(&video->m_packetCacheBase, cachePacket);
+ // use m_frame because when caching, it is not used in main thread
+ // we can't use currentFrame directly because we need to convert to RGB first
+ avcodec_decode_video(video->m_codecCtx,
+ video->m_frame, &frameFinished,
+ cachePacket->packet.data, cachePacket->packet.size);
+ if(frameFinished)
+ {
+ AVFrame * input = video->m_frame;
+
+ /* This means the data wasnt read properly, this check stops crashing */
+ if ( input->data[0]!=0 || input->data[1]!=0
+ || input->data[2]!=0 || input->data[3]!=0)
+ {
+ if (video->m_deinterlace)
+ {
+ if (avpicture_deinterlace(
+ (AVPicture*) video->m_frameDeinterlaced,
+ (const AVPicture*) video->m_frame,
+ video->m_codecCtx->pix_fmt,
+ video->m_codecCtx->width,
+ video->m_codecCtx->height) >= 0)
+ {
+ input = video->m_frameDeinterlaced;
+ }
+ }
+ // convert to RGB24
+ sws_scale(video->m_imgConvertCtx,
+ input->data,
+ input->linesize,
+ 0,
+ video->m_codecCtx->height,
+ currentFrame->frame->data,
+ currentFrame->frame->linesize);
+ // move frame to queue, this frame is necessarily the next one
+ currentFrame->framePosition = ++video->m_curPosition;
+ pthread_mutex_lock(&video->m_cacheMutex);
+ BLI_addtail(&video->m_frameCacheBase, currentFrame);
+ pthread_mutex_unlock(&video->m_cacheMutex);
+ currentFrame = NULL;
+ }
+ }
+ av_free_packet(&cachePacket->packet);
+ BLI_addtail(&video->m_packetCacheFree, cachePacket);
+ }
+ if (currentFrame && endOfFile)
+ {
+ // no more packet and end of file => put a special frame that indicates that
+ currentFrame->framePosition = -1;
+ pthread_mutex_lock(&video->m_cacheMutex);
+ BLI_addtail(&video->m_frameCacheBase, currentFrame);
+ pthread_mutex_unlock(&video->m_cacheMutex);
+ currentFrame = NULL;
+ // no need to stay any longer in this thread
+ break;
+ }
+ }
+ // small sleep to avoid unnecessary looping
+ PIL_sleep_ms(10);
+ }
+ // before quitting, put back the current frame to queue to allow freeing
+ if (currentFrame)
+ {
+ pthread_mutex_lock(&video->m_cacheMutex);
+ BLI_addtail(&video->m_frameCacheFree, currentFrame);
+ pthread_mutex_unlock(&video->m_cacheMutex);
+ }
+ return 0;
+}
+
+// start thread to cache video frame from file/capture/stream
+// this function should be called only when the position in the stream is set for the
+// first frame to cache
+bool VideoFFmpeg::startCache()
+{
+ if (!m_cacheStarted && m_isThreaded)
+ {
+ m_stopThread = false;
+ for (int i=0; i<CACHE_FRAME_SIZE; i++)
+ {
+ CacheFrame *frame = new CacheFrame();
+ frame->frame = allocFrameRGB();
+ BLI_addtail(&m_frameCacheFree, frame);
+ }
+ for (int i=0; i<CACHE_PACKET_SIZE; i++)
+ {
+ CachePacket *packet = new CachePacket();
+ BLI_addtail(&m_packetCacheFree, packet);
+ }
+ BLI_init_threads(&m_thread, cacheThread, 1);
+ BLI_insert_thread(&m_thread, this);
+ m_cacheStarted = true;
+ }
+ return m_cacheStarted;
+}
+
+void VideoFFmpeg::stopCache()
+{
+ if (m_cacheStarted)
+ {
+ m_stopThread = true;
+ BLI_end_threads(&m_thread);
+ // now delete the cache
+ CacheFrame *frame;
+ CachePacket *packet;
+ while ((frame = (CacheFrame *)m_frameCacheBase.first) != NULL)
+ {
+ BLI_remlink(&m_frameCacheBase, frame);
+ MEM_freeN(frame->frame->data[0]);
+ av_free(frame->frame);
+ delete frame;
+ }
+ while ((frame = (CacheFrame *)m_frameCacheFree.first) != NULL)
+ {
+ BLI_remlink(&m_frameCacheFree, frame);
+ MEM_freeN(frame->frame->data[0]);
+ av_free(frame->frame);
+ delete frame;
+ }
+ while((packet = (CachePacket *)m_packetCacheBase.first) != NULL)
+ {
+ BLI_remlink(&m_packetCacheBase, packet);
+ av_free_packet(&packet->packet);
+ delete packet;
+ }
+ while((packet = (CachePacket *)m_packetCacheFree.first) != NULL)
+ {
+ BLI_remlink(&m_packetCacheFree, packet);
+ delete packet;
+ }
+ m_cacheStarted = false;
+ }
+}
+
+void VideoFFmpeg::releaseFrame(AVFrame* frame)
+{
+ if (frame == m_frameRGB)
+ {
+ // this is not a frame from the cache, ignore
+ return;
+ }
+ // this frame MUST be the first one of the queue
+ pthread_mutex_lock(&m_cacheMutex);
+ CacheFrame *cacheFrame = (CacheFrame *)m_frameCacheBase.first;
+ assert (cacheFrame != NULL && cacheFrame->frame == frame);
+ BLI_remlink(&m_frameCacheBase, cacheFrame);
+ BLI_addtail(&m_frameCacheFree, cacheFrame);
+ pthread_mutex_unlock(&m_cacheMutex);
+}
+
// open video file
void VideoFFmpeg::openFile (char * filename)
{
@@ -280,8 +527,12 @@ void VideoFFmpeg::openFile (char * filename)
VideoBase::openFile(filename);
if (
+ // ffmpeg reports that http source are actually non stream
+ // but it is really not desirable to seek on http file, so force streaming.
+ // It would be good to find this information from the context but there are no simple indication
+ !strncmp(filename, "http://", 7) ||
#ifdef FFMPEG_PB_IS_POINTER
- m_formatCtx->pb && m_formatCtx->pb->is_streamed
+ (m_formatCtx->pb && m_formatCtx->pb->is_streamed)
#else
m_formatCtx->pb.is_streamed
#endif
@@ -304,7 +555,13 @@ void VideoFFmpeg::openFile (char * filename)
m_avail = false;
play();
}
-
+ // check if we should do multi-threading?
+ if (!m_isImage && BLI_system_thread_count() > 1)
+ {
+ // never thread image: there are no frame to read ahead
+ // no need to thread if the system has a single core
+ m_isThreaded = true;
+ }
}
@@ -385,6 +642,12 @@ void VideoFFmpeg::openCam (char * file, short camIdx)
m_formatCtx->flags |= AVFMT_FLAG_NONBLOCK;
// open base class
VideoBase::openCam(file, camIdx);
+ // check if we should do multi-threading?
+ if (BLI_system_thread_count() > 1)
+ {
+ // no need to thread if the system has a single core
+ m_isThreaded = true;
+ }
}
// play video
@@ -427,9 +690,12 @@ void VideoFFmpeg::setRange (double start, double stop)
try
{
// set range
- VideoBase::setRange(start, stop);
- // set range for video
- setPositions();
+ if (m_isFile)
+ {
+ VideoBase::setRange(start, stop);
+ // set range for video
+ setPositions();
+ }
}
CATCH_EXCP;
}
@@ -451,43 +717,61 @@ void VideoFFmpeg::calcImage (unsigned int texId)
// load frame from video
void VideoFFmpeg::loadFrame (void)
{
- // get actual time
- double actTime = PIL_check_seconds_timer() - m_startTime;
- // if video has ended
- if (m_isFile && actTime * m_frameRate >= m_range[1])
- {
- // if repeats are set, decrease them
- if (m_repeat > 0)
- --m_repeat;
- // if video has to be replayed
- if (m_repeat != 0)
- {
- // reset its position
- actTime -= (m_range[1] - m_range[0]) / m_frameRate;
- m_startTime += (m_range[1] - m_range[0]) / m_frameRate;
- }
- // if video has to be stopped, stop it
- else
- m_status = SourceStopped;
- }
- // if video is playing
if (m_status == SourcePlaying)
{
+ // get actual time
+ double startTime = PIL_check_seconds_timer();
+ double actTime = startTime - m_startTime;
+ // if video has ended
+ if (m_isFile && actTime * m_frameRate >= m_range[1])
+ {
+ // in any case, this resets the cache
+ stopCache();
+ // if repeats are set, decrease them
+ if (m_repeat > 0)
+ --m_repeat;
+ // if video has to be replayed
+ if (m_repeat != 0)
+ {
+ // reset its position
+ actTime -= (m_range[1] - m_range[0]) / m_frameRate;
+ m_startTime += (m_range[1] - m_range[0]) / m_frameRate;
+ }
+ // if video has to be stopped, stop it
+ else
+ {
+ m_status = SourceStopped;
+ return;
+ }
+ }
// actual frame
- long actFrame = m_isFile ? long(actTime * actFrameRate()) : m_lastFrame + 1;
+ long actFrame = (m_isImage) ? m_lastFrame+1 : long(actTime * actFrameRate());
// if actual frame differs from last frame
if (actFrame != m_lastFrame)
{
+ AVFrame* frame;
// get image
- if(grabFrame(actFrame))
+ if((frame = grabFrame(actFrame)) != NULL)
{
- AVFrame* frame = getFrame();
+ if (!m_isFile && !m_cacheStarted)
+ {
+ // streaming without cache: detect synchronization problem
+ double execTime = PIL_check_seconds_timer() - startTime;
+ if (execTime > 0.005)
+ {
+ // exec time is too long, it means that the function was blocking
+ // resynchronize the stream from this time
+ m_startTime += execTime;
+ }
+ }
// save actual frame
m_lastFrame = actFrame;
// init image, if needed
init(short(m_codecCtx->width), short(m_codecCtx->height));
// process image
process((BYTE*)(frame->data[0]));
+ // finished with the frame, release it so that cache can reuse it
+ releaseFrame(frame);
// in case it is an image, automatically stop reading it
if (m_isImage)
{
@@ -495,6 +779,12 @@ void VideoFFmpeg::loadFrame (void)
// close the file as we don't need it anymore
release();
}
+ } else if (!m_isFile)
+ {
+ // we didn't get a frame and we are streaming, this may be due to
+ // a delay in the network or because we are getting the frame too fast.
+ // In the later case, shift time by a small amount to compensate for a drift
+ m_startTime += 0.01;
}
}
}
@@ -507,77 +797,135 @@ void VideoFFmpeg::setPositions (void)
// set video start time
m_startTime = PIL_check_seconds_timer();
// if file is played and actual position is before end position
- if (m_isFile && !m_eof && m_lastFrame >= 0 && m_lastFrame < m_range[1] * actFrameRate())
+ if (!m_eof && m_lastFrame >= 0 && (!m_isFile || m_lastFrame < m_range[1] * actFrameRate()))
// continue from actual position
m_startTime -= double(m_lastFrame) / actFrameRate();
- else
+ else {
m_startTime -= m_range[0];
+ // start from begining, stop cache just in case
+ stopCache();
+ }
}
// position pointer in file, position in second
-bool VideoFFmpeg::grabFrame(long position)
+AVFrame *VideoFFmpeg::grabFrame(long position)
{
AVPacket packet;
int frameFinished;
int posFound = 1;
bool frameLoaded = false;
long long targetTs = 0;
+ CacheFrame *frame;
- // first check if the position that we are looking for is in the preseek range
- // if so, just read the frame until we get there
- if (position > m_curPosition + 1
- && m_preseek
- && position - (m_curPosition + 1) < m_preseek)
+ if (m_cacheStarted)
{
- while(av_read_frame(m_formatCtx, &packet)>=0)
+ // when cache is active, we must not read the file directly
+ do {
+ pthread_mutex_lock(&m_cacheMutex);
+ frame = (CacheFrame *)m_frameCacheBase.first;
+ pthread_mutex_unlock(&m_cacheMutex);
+ // no need to remove the frame from the queue: the cache thread does not touch the head, only the tail
+ if (frame == NULL)
+ {
+ // no frame in cache, in case of file it is an abnormal situation
+ if (m_isFile)
+ {
+ // go back to no threaded reading
+ stopCache();
+ break;
+ }
+ return NULL;
+ }
+ if (frame->framePosition == -1)
+ {
+ // this frame mark the end of the file (only used for file)
+ // leave in cache to make sure we don't miss it
+ m_eof = true;
+ return NULL;
+ }
+ // for streaming, always return the next frame,
+ // that's what grabFrame does in non cache mode anyway.
+ if (!m_isFile || frame->framePosition == position)
+ {
+ return frame->frame;
+ }
+ // this frame is not useful, release it
+ pthread_mutex_lock(&m_cacheMutex);
+ BLI_remlink(&m_frameCacheBase, frame);
+ BLI_addtail(&m_frameCacheFree, frame);
+ pthread_mutex_unlock(&m_cacheMutex);
+ } while (true);
+ }
+ // come here when there is no cache or cache has been stopped
+ // locate the frame, by seeking if necessary (seeking is only possible for files)
+ if (m_isFile)
+ {
+ // first check if the position that we are looking for is in the preseek range
+ // if so, just read the frame until we get there
+ if (position > m_curPosition + 1
+ && m_preseek
+ && position - (m_curPosition + 1) < m_preseek)
{
- if (packet.stream_index == m_videoStream)
+ while(av_read_frame(m_formatCtx, &packet)>=0)
{
- avcodec_decode_video(
- m_codecCtx,
- m_frame, &frameFinished,
- packet.data, packet.size);
- if (frameFinished)
- m_curPosition++;
+ if (packet.stream_index == m_videoStream)
+ {
+ avcodec_decode_video(
+ m_codecCtx,
+ m_frame, &frameFinished,
+ packet.data, packet.size);
+ if (frameFinished)
+ m_curPosition++;
+ }
+ av_free_packet(&packet);
+ if (position == m_curPosition+1)
+ break;
}
- av_free_packet(&packet);
- if (position == m_curPosition+1)
- break;
}
- }
- // if the position is not in preseek, do a direct jump
- if (position != m_curPosition + 1)
- {
- double timeBase = av_q2d(m_formatCtx->streams[m_videoStream]->time_base);
- long long pos = (long long)
- ((long long) (position - m_preseek) * AV_TIME_BASE / m_baseFrameRate);
- long long startTs = m_formatCtx->streams[m_videoStream]->start_time;
+ // if the position is not in preseek, do a direct jump
+ if (position != m_curPosition + 1)
+ {
+ double timeBase = av_q2d(m_formatCtx->streams[m_videoStream]->time_base);
+ long long pos = (long long)
+ ((long long) (position - m_preseek) * AV_TIME_BASE / m_baseFrameRate);
+ long long startTs = m_formatCtx->streams[m_videoStream]->start_time;
- if (pos < 0)
- pos = 0;
+ if (pos < 0)
+ pos = 0;
- if (startTs != AV_NOPTS_VALUE)
- pos += (long long)(startTs * AV_TIME_BASE * timeBase);
+ if (startTs != AV_NOPTS_VALUE)
+ pos += (long long)(startTs * AV_TIME_BASE * timeBase);
- if (position <= m_curPosition || !m_eof)
- {
- // no need to seek past the end of the file
- if (av_seek_frame(m_formatCtx, -1, pos, AVSEEK_FLAG_BACKWARD) >= 0)
+ if (position <= m_curPosition || !m_eof)
{
- // current position is now lost, guess a value.
- // It's not important because it will be set at this end of this function
- m_curPosition = position - m_preseek - 1;
+ // no need to seek past the end of the file
+ if (av_seek_frame(m_formatCtx, -1, pos, AVSEEK_FLAG_BACKWARD) >= 0)
+ {
+ // current position is now lost, guess a value.
+ // It's not important because it will be set at this end of this function
+ m_curPosition = position - m_preseek - 1;
+ }
}
- }
- // this is the timestamp of the frame we're looking for
- targetTs = (long long)(((double) position) / m_baseFrameRate / timeBase);
- if (startTs != AV_NOPTS_VALUE)
- targetTs += startTs;
+ // this is the timestamp of the frame we're looking for
+ targetTs = (long long)(((double) position) / m_baseFrameRate / timeBase);
+ if (startTs != AV_NOPTS_VALUE)
+ targetTs += startTs;
- posFound = 0;
- avcodec_flush_buffers(m_codecCtx);
+ posFound = 0;
+ avcodec_flush_buffers(m_codecCtx);
+ }
+ } else if (m_isThreaded)
+ {
+ // cache is not started but threading is possible
+ // better not read the stream => make take some time, better start caching
+ if (startCache())
+ return NULL;
+ // Abnormal!!! could not start cache, fall back on direct read
+ m_isThreaded = false;
}
+ // find the correct frame, in case of streaming and no cache, it means just
+ // return the next frame. This is not quite correct, may need more work
while(av_read_frame(m_formatCtx, &packet)>=0)
{
if(packet.stream_index == m_videoStream)
@@ -632,10 +980,22 @@ bool VideoFFmpeg::grabFrame(long position)
}
av_free_packet(&packet);
}
- m_eof = !frameLoaded;
+ m_eof = m_isFile && !frameLoaded;
if (frameLoaded)
+ {
m_curPosition = position;
- return frameLoaded;
+ if (m_isThreaded)
+ {
+ // normal case for file: first locate, then start cache
+ if (!startCache())
+ {
+ // Abnormal!! could not start cache, return to non-cache mode
+ m_isThreaded = false;
+ }
+ }
+ return m_frameRGB;
+ }
+ return NULL;
}
diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h
index e60f1727aab..51ce2c4eebe 100644
--- a/source/gameengine/VideoTexture/VideoFFmpeg.h
+++ b/source/gameengine/VideoTexture/VideoFFmpeg.h
@@ -24,12 +24,17 @@ http://www.gnu.org/copyleft/lesser.txt.
#ifdef WITH_FFMPEG
extern "C" {
+#include <pthread.h>
#include <ffmpeg/avformat.h>
#include <ffmpeg/avcodec.h>
#include <ffmpeg/rational.h>
#include <ffmpeg/swscale.h>
+#include "DNA_listBase.h"
+#include "BLI_threads.h"
+#include "BLI_blenlib.h"
}
+
#if LIBAVFORMAT_VERSION_INT < (49 << 16)
#define FFMPEG_OLD_FRAME_RATE 1
#else
@@ -54,6 +59,8 @@ static inline AVCodecContext* get_codec_from_stream(AVStream* stream)
#include "VideoBase.h"
+#define CACHE_FRAME_SIZE 5
+#define CACHE_PACKET_SIZE 30
// type VideoFFmpeg declaration
class VideoFFmpeg : public VideoBase
@@ -91,7 +98,6 @@ public:
char *getImageName(void) { return (m_isImage) ? m_imageName.Ptr() : NULL; }
protected:
-
// format and codec information
AVCodec *m_codec;
AVFormatContext *m_formatCtx;
@@ -138,6 +144,9 @@ protected:
/// is file an image?
bool m_isImage;
+ /// is image loading done in a separate thread?
+ bool m_isThreaded;
+
/// keep last image name
STR_String m_imageName;
@@ -157,10 +166,37 @@ protected:
int openStream(const char *filename, AVInputFormat *inputFormat, AVFormatParameters *formatParams);
/// check if a frame is available and load it in pFrame, return true if a frame could be retrieved
- bool grabFrame(long frame);
-
- /// return the frame in RGB24 format, the image data is found in AVFrame.data[0]
- AVFrame* getFrame(void) { return m_frameRGB; }
+ AVFrame* grabFrame(long frame);
+
+ /// in case of caching, put the frame back in free queue
+ void releaseFrame(AVFrame* frame);
+
+ /// start thread to load the video file/capture/stream
+ bool startCache();
+ void stopCache();
+
+private:
+ typedef struct {
+ Link link;
+ long framePosition;
+ AVFrame *frame;
+ } CacheFrame;
+ typedef struct {
+ Link link;
+ AVPacket packet;
+ } CachePacket;
+
+ bool m_stopThread;
+ bool m_cacheStarted;
+ ListBase m_thread;
+ ListBase m_frameCacheBase; // list of frames that are ready
+ ListBase m_frameCacheFree; // list of frames that are unused
+ ListBase m_packetCacheBase; // list of packets that are ready for decoding
+ ListBase m_packetCacheFree; // list of packets that are unused
+ pthread_mutex_t m_cacheMutex;
+
+ AVFrame *allocFrameRGB();
+ static void *cacheThread(void *);
};
inline VideoFFmpeg * getFFmpeg (PyImage * self)
diff --git a/source/kernel/SConscript b/source/kernel/SConscript
index 21584583844..908e059ceab 100644
--- a/source/kernel/SConscript
+++ b/source/kernel/SConscript
@@ -7,4 +7,4 @@ sources += ' gen_system/SYS_System.cpp'
incs = 'gen_messaging gen_system #/intern/string #/intern/moto/include #/source/blender/blenloader '
-env.BlenderLib ( 'bf_kernel', Split(sources), Split(incs), [], libtype = ['core', 'player'], priority = [15, 150] )
+env.BlenderLib ( 'bf_kernel', Split(sources), Split(incs), [], libtype = ['core', 'player'], priority = [400, 150] )
diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk
index 495eb60a7f8..9ca458e8371 100644
--- a/source/nan_definitions.mk
+++ b/source/nan_definitions.mk
@@ -111,6 +111,7 @@ endif
export WITH_OPENEXR ?= true
export WITH_DDS ?= true
+ export WITH_OPENJPEG ?= true
ifeq ($(OS),windows)
export NAN_WINTAB ?= $(LCGDIR)/wintab
@@ -135,9 +136,9 @@ endif
else
ifeq ($(OS),linux)
ifeq ($(WITH_OPENEXR), true)
- NAN_OPENEXR?=$(shell pkg-config --variable=prefix OpenEXR )
- NAN_OPENEXR_INC?=$(shell pkg-config --cflags OpenEXR )
- NAN_OPENEXR_LIBS?=$(addprefix ${NAN_OPENEXR}/lib/lib,$(addsuffix .a,$(shell pkg-config --libs-only-l OpenEXR | sed -s "s/-l//g" )))
+ export NAN_OPENEXR?=$(shell pkg-config --variable=prefix OpenEXR )
+ export NAN_OPENEXR_INC?=$(shell pkg-config --cflags OpenEXR )
+ export NAN_OPENEXR_LIBS?=$(addprefix ${NAN_OPENEXR}/lib/lib,$(addsuffix .a,$(shell pkg-config --libs-only-l OpenEXR | sed -s "s/-l//g" )))
endif
else
ifeq ($(OS), solaris)
diff --git a/tools/Blender.py b/tools/Blender.py
index a087223bdb5..8286a3a4714 100644
--- a/tools/Blender.py
+++ b/tools/Blender.py
@@ -433,11 +433,11 @@ class BlenderEnvironment(SConsEnvironment):
lenv.Append(CCFLAGS = lenv['BF_PROFILE_CCFLAGS'])
lenv.Append(CXXFLAGS = lenv['BF_PROFILE_CXXFLAGS'])
if compileflags:
- lenv.Append(CFLAGS = compileflags)
+ lenv.Replace(CFLAGS = compileflags)
if cc_compileflags:
- lenv.Append(CCFLAGS = cc_compileflags)
+ lenv.Replace(CCFLAGS = cc_compileflags)
if cxx_compileflags:
- lenv.Append(CXXFLAGS = cxx_compileflags)
+ lenv.Replace(CXXFLAGS = cxx_compileflags)
lenv.Append(CFLAGS = lenv['C_WARN'])
lenv.Append(CCFLAGS = lenv['CC_WARN'])
lenv.Append(CXXFLAGS = lenv['CXX_WARN'])
diff --git a/tools/btools.py b/tools/btools.py
index 6cf9058886b..3c6b63c30cc 100755
--- a/tools/btools.py
+++ b/tools/btools.py
@@ -44,7 +44,7 @@ def validate_arguments(args, bc):
'BF_GETTEXT', 'BF_GETTEXT_INC', 'BF_GETTEXT_LIB', 'BF_GETTEXT_LIBPATH',
'WITH_BF_ICONV', 'BF_ICONV', 'BF_ICONV_INC', 'BF_ICONV_LIB', 'BF_ICONV_LIBPATH',
'WITH_BF_ODE', 'BF_ODE', 'BF_ODE_INC', 'BF_ODE_LIB',
- 'WITH_BF_GAMEENGINE', 'WITH_BF_BULLET', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB',
+ 'WITH_BF_GAMEENGINE', 'WITH_BF_SOLID', 'WITH_BF_BULLET', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB',
'BF_SOLID', 'BF_SOLID_INC', 'BF_WINTAB', 'BF_WINTAB_INC',
'WITH_BF_YAFRAY',
'WITH_BF_FREETYPE', 'BF_FREETYPE', 'BF_FREETYPE_INC', 'BF_FREETYPE_LIB', 'BF_FREETYPE_LIBPATH',
@@ -264,6 +264,7 @@ def read_opts(cfg, args):
('BF_BULLET_INC', 'Bullet include path', ''),
('BF_BULLET_LIB', 'Bullet library', ''),
+ (BoolVariable('WITH_BF_SOLID', 'Use Sumo/Solid deprecated physics system if true', True)),
('BF_SOLID', 'Solid base dir', '#/extern/solid'),
('BF_SOLID_INC', 'Solid include path', ''),
('BF_WINTAB', 'WinTab base dir', ''),